簡體   English   中英

將貨幣存儲在 Java double(浮點數)中,沒有任何數學運算,總是准確的嗎?

[英]Is storing currency in Java double (floating point), without any math, always accurate?

當然不應該做數學,因為結果不會准確。 浮點值不適用於此。

但是僅僅存儲值呢? 就我個人而言,對於 String 或 Long,我會使用 go,但看起來我有時可能被迫與堅持使用浮點類型的系統進行交互。

看起來0.00 到 2.00 之間的值是 100% 准確的 - 請參見下面的代碼。 但真的是這樣嗎? 為什么? 當我簡單地做double v = 0.01時不應該已經有問題了嗎?

public static void main(final String[] args) {

    final DecimalFormat df = new DecimalFormat("0.0000000000000000000000000", DecimalFormatSymbols.getInstance(Locale.US));
    final BigDecimal aHundred = new BigDecimal("100");
    final BigDecimal oneHundredth = BigDecimal.ONE.divide(aHundred);
    for (int i = 0; i < 200; i++) {
        BigDecimal dec = oneHundredth;

        for (int ii = 0; ii < i; ii++) {
            dec = dec.add(oneHundredth);
        }

        final double v = dec.doubleValue();

        System.err.println(v);
        System.err.println(df.format(v));
    }
    System.exit(0);
}

Output:

0.01
0.0100000000000000000000000
0.02
0.0200000000000000000000000
0.03
0.0300000000000000000000000
...
1.38
1.3800000000000000000000000
1.39
1.3900000000000000000000000
1.4
1.4000000000000000000000000
1.41
1.4100000000000000000000000
...
1.99
1.9900000000000000000000000
2.0
2.0000000000000000000000000

從十進制轉換為基於二進制的浮點數或反之亦然是數學。 它是一種將結果舍入到最接近的可表示值的操作。

當您將 .01 轉換為double時,結果正好是 0.01000000000000000020816681711721685132943093776702880859375。 Java 的默認顯示格式可能顯示為“0.01”,但實際值為 0.01000000000000000020816681711721685132943093776702880859375。

Java 的double精度格式的精度是這樣的,如果任何具有最多 15 個有效小數位的十進制數字四舍五入到最接近的可表示double精度,然后將該double精度四舍五入到最接近的具有 15 個或更少有效數字的十進制數字,結果將是原號碼。

因此,您可以使用double來存儲最多 15 位有效數字(在指數范圍內)的任何十進制數字,並且可以通過將其轉換回十進制來恢復原始數字。 超過 15 位數字,一些數字將被往返更改。

將貨幣存儲在 Java double(浮點數)中,沒有任何數學運算,總是准確的嗎?

如果您將貨幣值表示為最小貨幣單位(例如,美分)的倍數,那么您實際上可以使用 53 位精度……計算結果為 9.0 x 10 15美分,或 9.0 x 10 13美元。

(就規模而言,美國國債目前約為 2.8 x 13美元。)

如果您嘗試用(比如)浮點美元(使用double )表示貨幣值,那么大多數美分值根本無法精確表示。 只有 25 美分的倍數可以精確表示為二進制浮點數。

簡而言之,即使您不對值執行算術運算,它也可能不精確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM