」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 如果需要準確答案,請避免浮動和雙精度

如果需要準確答案,請避免浮動和雙精度

發佈於2024-11-06
瀏覽:961

Item  Evite o float e o double caso sejam necessárias respostas exatas

float 和 double 問題:

  • 專為科學和數學計算而設計,執行二元浮點運算。
  • 不適合貨幣計算或需要精確答案的情況。
  • 無法準確表示10的負次方,例如0.1,從而導致錯誤。

範例1:
減去美元金額時計算錯誤:

System.out.println(1.03 - 0.42);  // Resultado: 0.6100000000000001

範例2:
以每件 10 美分的價格購買 9 件商品時出錯:

System.out.println(1.00 - 9 * 0.10);  // Resultado: 0.09999999999999998

即使四捨五入,錯誤仍然存在。
累進計算存在問題,例如以 0.10 到 1.00 的增量價格購買糖果時。

範例3:
買糖果時出錯,直到你沒錢了:

double funds = 1.00;
for (double price = 0.10; funds >= price; price  = 0.10) {
    funds -= price;
}
System.out.println(funds);  // Resultado: 0.3999999999999999

解決方案1:使用BigDecimal

  • 非常適合財務計算和精確度至關重要的情況。
  • 避免使用 BigDecimal 的雙重建構函數,首選 String 建構函數。

BigDecimal 範例:

BigDecimal funds = new BigDecimal("1.00");
BigDecimal price = new BigDecimal("0.10");
int itemsBought = 0;

while (funds.compareTo(price) >= 0) {
    funds = funds.subtract(price);
    price = price.add(new BigDecimal("0.10"));
    itemsBought  ;
}
System.out.println(itemsBought   " items bought. Money left: "   funds);  
// Resultado: 4 items bought. Money left: 0.00

計算現在很精確。

BigDecimal的缺點:

  • 使用起來不如原始型方便。
  • 速度較慢,尤其是對於大量操作。

解決方案2:使用int或長

  • 為了避免精確度問題,請使用 int 或 long 而不是以 double 表示的美元,以美分為單位進行計算。

int 範例(以分為單位):

int funds = 100;  // 1.00 dólar = 100 centavos
int price = 10;   // 0.10 dólar = 10 centavos
int itemsBought = 0;

while (funds >= price) {
    funds -= price;
    price  = 10;
    itemsBought  ;
}
System.out.println(itemsBought   " items bought. Money left: "   funds);  
// Resultado: 4 items bought. Money left: 0

計算又快又準。

結論:

  • 不要使用 float 或 double 進行需要精確精確度的計算。
  • 使用 BigDecimal 進行貨幣計算或需要小數精度的情況。
  • 使用 int 或 long 進行不涉及大數的金融計算,以分為單位進行計算。

選擇:

  • 最多 9 位數字,請使用 int。
  • 對於最多 18 位數字,請使用 long。
  • 對於較大數量,請使用 BigDecimal。
  • 此摘要表明,根據上下文,在 BigDecimal、int 或 long 之間進行選擇可以優化精度和性能。
版本聲明 本文轉載於:https://dev.to/giselecoder/item-60-evite-o-float-e-o-double-caso-sejam-necessarias-respostas-exatas-3mep?1如有侵犯,請聯絡study_golang@163 .com刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3