Java 四舍五入问题减去双倍

Java 四舍五入问题减去双倍,java,numeric,Java,Numeric,这是我的密码 led.cost=led.cost-((Ledger)mdisellList.get(ms)).cost; led.cost的初始值为4119.7,mdisellList.cost的初始值为172.485。两者都是双重数据类型 我在调试0.7或0.485之后的小数时,在该变量中看到了这些值。在这一行之前没有进行四舍五入。从4119.7中减去172.485,结果为3947.214999997,而不是3947.215 我想要准确的3947.215而不是3947.214999997。好

这是我的密码

led.cost=led.cost-((Ledger)mdisellList.get(ms)).cost;
led.cost的初始值为4119.7,mdisellList.cost的初始值为172.485。两者都是双重数据类型

我在调试0.7或0.485之后的小数时,在该变量中看到了这些值。在这一行之前没有进行四舍五入。从4119.7中减去172.485,结果为3947.214999997,而不是3947.215


我想要准确的3947.215而不是3947.214999997。

好!好的同龄人的压力是双重的

如果您知道如何在Java中处理double,或者如果您的项目需求不需要财务数学,那么在Java中使用double是可以的

但是,如果您不能完全确定浮点运算是如何工作的,请远离double,否则会受到诸如

System.out.println(0.01 + 5.02);
如果您不知道如何处理double,那么更好的选择是坚持使用专门为此目的而设计的库,例如

java.math...

将答案四舍五入

例如:

double valToRound = 172.485 - 4119.7;   
DecimalFormat df = new DecimalFormat("#.###");
System.out.println(df.format(valToRound));

结果:-3947.215

不幸的是,在这些情况下,必须使用BigDecimal而不是double

double是2位负幂的和!,这是一种类似0.10的十进制表示法,只能近似为:1/16+1/32+。计算时,偏差会增大并变得可见

要使用double,就必须经常使用格式化输出,DecimalFormat,甚至对于使用十进制逗号和1000个分隔符的区域设置也是一件好事。但人们也需要不断地围绕事物。考虑到税收和其他法律,有时是6位小数等等

BigDecimal是一种不可变的值类型。它需要一个刻度/精度来设置,并且有笨拙的加法、减法和乘法方法

然后是数据库端。根据数据库系统的不同,小数可能优先于双精度以上


第三种选择是使用分,长,但这也是间接的。

您可以将金额转换为较小的货币单位。方法 1欧元等于100美分。如果您有0.01欧元,则将其作为1美分进行计算,并使用BigDecimal和舍入模式将其转换回欧元


请发布您的代码。欢迎来到浮点数学的奇妙世界。使用大小数避免这些问题。moneydouble的大小数不适用于货币值@user3580294的注释应该给您一个提示,使用大小数我认为您应该改写您的第一句话。如果浮点错误正常,则可以使用双变量进行浮点计算。您可能应该说,在精度很重要的情况下,不要在浮点计算中使用double,这是非常糟糕的措辞。你可以在没有这些库的情况下编写浮点算法,但仍然可以得到结果——你只需要知道浮点算法是如何工作的。使用双值计算的精度约为15位小数。对于大多数应用来说,这已经足够了。在大规模模拟中,性能考虑超过了精确的精度考虑?我认为双精度在很多情况下已经足够好了,否则没有人会使用它们……第一行相当于说不要在浮点计算中使用浮点计算。我不知道为什么我会得到选票。问题清楚地说明了我想要的是精确的3947.215,而不是3947.214999997。这就实现了这一点。不要拿走我的互联网点数!:嗯,我没有投你反对票,但我很快就会投你的。该点不是为了掩盖浮点运算产生的错误。在金融数学中,你必须精确计算,否则税务员会来惩罚你。每个人都投了反对票,所以我现在也回答了。我不知道。我对大小数的答案投了更高的票,因为我认为这是一条艰难的道路。好吧,无论如何,干杯。最终你会遇到21%的增值税或2.25%的利率这样的计算,所以你必须把小数点进一步向右推。当你必须除以3或7时,你将永远向前推,一天-
new BigDecimal("0.10"); // Works perfectly.
new BigDecimal(0.10); // Should not be used, looses precision 2,
                      // and has epsilon error.