Java 使BigDecimal截断而不是四舍五入

Java 使BigDecimal截断而不是四舍五入,java,double,rounding,bigdecimal,Java,Double,Rounding,Bigdecimal,我在应用程序中使用BigDecimal来处理正数,我想让它在第四个正数之后截断小数。 通过RoundingMode.DOWN,我似乎几乎找到了我想要的东西,但是当BigDecimal是从double创建时,会出现一些问题 例如: System.out.println("123.11119 = " + new BigDecimal("123.11119").setScale(4, RoundingMode.DOWN)); //Print 123.1111 which is exactly what

我在应用程序中使用BigDecimal来处理正数,我想让它在第四个正数之后截断小数。 通过RoundingMode.DOWN,我似乎几乎找到了我想要的东西,但是当BigDecimal是从double创建时,会出现一些问题

例如:

System.out.println("123.11119 = " + new BigDecimal("123.11119").setScale(4, RoundingMode.DOWN)); //Print 123.1111 which is exactly what I want
System.out.println("123.1111 = " + new BigDecimal("123.1111").setScale(4, RoundingMode.DOWN)); //So does this one
但是,以下打印的
123.1110
根本不是我想要的:

System.out.println("123.1111 = " + new BigDecimal(123.1111d).setScale(4, RoundingMode.DOWN)); 

这是因为表示问题

实际上,123.1111d的值可能类似于123.111091231918498


这就是为什么在需要精确值时建议使用字符串构造函数。

问题在于
123.1111d
可能存储为
123.1110999999
,从而解决问题。是的。不要从双精度中创建大小数。@DavidWallace为什么?原始的双精度仍然不准确。因为将其转换为字符串具有正确的智能,可以选择小数位数最少的数字,小数位数在四舍五入到该双精度的范围内。这意味着它将选择您实际需要的值。例如,
Double.toString(123.1111)
将为您提供
“123.1111”
。当你的价值已经翻倍时,这是唯一合理的做法。当然,你应该避免一开始就将十进制数存储为双倍数,但是如果数据来自你无法控制的某个来源,你就没有选择的余地了。好吧。我接受你的答案,我想解决办法是“不要使用双构造函数”!