日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

复合双重错误

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 复合双重错误 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

總覽

在上一篇文章中,我概述了為什么BigDecimal大部分時間都不是答案。 雖然可以構造double會產生錯誤的情況,但在BigDecimal遇到錯誤的情況下構造情況也一樣容易。

BigDecimal更容易正確,但更容易出錯。

軼事證據表明,初級開發人員在正確使用BigDecimal時不會像在四舍五入時獲得兩倍的麻煩一樣。 但是,我對此表示懷疑,因為在BigDecimal中,錯誤也容易被忽略。

讓我們以這個例子為例,其中double會產生錯誤的答案。

double d = 1.00; d /= 49; d *= 49 * 2; System.out.println("d=" + d);BigDecimal bd = BigDecimal.ONE; bd = bd .divide(BigDecimal.valueOf(49), 2, BigDecimal.ROUND_HALF_UP); bd = bd.multiply(BigDecimal.valueOf(49*2)); System.out.println("bd=" + bd);

版畫

d=1.9999999999999998 bd=1.96

在這種情況下,double看起來是錯誤的,它需要四舍五入,這將給出2.0的正確答案。 但是BigDecimal看起來正確,但這不是由于表示錯誤。 我們可以更改除法以使用更高的精度,但是盡管可以控制該誤差有多小,但總會出現表示錯誤。

您必須確保數字是實數并使用四舍五入。

即使使用BigDecimal,也必須使用適當的舍入。 假設您有一筆$ 1,000,000的貸款,并且每天要申請0.0005%的利息。 該帳戶只能有一個整數,因此需要四舍五入才能使這筆錢成為實際金額。 如果不這樣做,需要多長時間才能產生1美分的差異?

double interest = 0.0005; BigDecimal interestBD = BigDecimal.valueOf(interest);double amount = 1e6; BigDecimal amountBD = BigDecimal.valueOf(amount); BigDecimal amountBD2 = BigDecimal.valueOf(amount);long i = 0; do {System.out.printf("%,d: BigDecimal: $%s, BigDecimal: $%s%n", i, amountBD, amountBD2);i++;amountBD = amountBD.add(amountBD.multiply(interestBD).setScale(2, BigDecimal.ROUND_HALF_UP));amountBD2 = amountBD2.add(amountBD2.multiply(interestBD));} while (amountBD2.subtract(amountBD).abs().compareTo(BigDecimal.valueOf(0.01)) < 0); System.out.printf("After %,d iterations the error was 1 cent and you owe %s%n", i, amountBD);

最終打印

8: BigDecimal: $1004007.00, BigDecimal: $1004007.00700437675043756250390625000000000000000 After 9 iterations the error was 1 cent and you owe 1004509.00

您可以四舍五入結果,但是即使您使用BigDecimal,這也掩蓋了您差一分錢的事實。

double最終出現表示錯誤

即使您使用適當的舍入,double也會給您不正確的結果。 它比上一個示例晚得多。

double interest = 0.0005; BigDecimal interestBD = BigDecimal.valueOf(interest); double amount = 1e6; BigDecimal amountBD = BigDecimal.valueOf(amount); long i = 0; do {System.out.printf("%,d: double: $%.2f, BigDecimal: $%s%n", i, amount, amountBD);i++;amount = round2(amount + amount * interest);amountBD = amountBD.add(amountBD.multiply(interestBD).setScale(2, BigDecimal.ROUND_HALF_UP)); } while (BigDecimal.valueOf(amount).subtract(amountBD).abs().compareTo(BigDecimal.valueOf(0.01)) < 0); System.out.printf("After %,d iterations the error was 1 cent and you owe %s%n", i, amountBD);

最終打印

22,473: double: $75636308370.01, BigDecimal: $75636308370.01 After 22,474 iterations the error was 1 cent and you owe 75674126524.20

從IT角度來看,我們有一個錯誤的誤差,從業務角度來看,我們有一個客戶超過9年沒有還款,并且還欠銀行756億美元,足以使該銀行倒閉。 如果只有IT人員使用過BigDecimal !?

結論

我的最終建議是,您應該使用自己喜歡的東西,不要忘記取整,不要使用實數,而不要使用任何數學運算法則,例如,我可以賺一分錢,還是可以交易幾分之一的份額。 不要忘記業務視角。 您可能會發現BigDecimal對您的公司,項目或團隊更有意義。

不要以為BigDecimal是唯一的方法,不要以為雙面問題也不適用于BigDecimal。 BigDecimal并不是最佳實踐編碼的門票,因為自滿是引入錯誤的肯定方法。

翻譯自: https://www.javacodegeeks.com/2014/07/compounding-double-error.html

總結

以上是生活随笔為你收集整理的复合双重错误的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。