”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 如果需要准确答案,请避免浮动和双精度

如果需要准确答案,请避免浮动和双精度

发布于2024-11-06
浏览:759

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或long

  • 为了避免精度问题,请使用 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如有侵犯,请联系[email protected]删除
最新教程 更多>

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3