Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么BigDecimal在四舍五入后返回这个值?_Java_Double_Bigdecimal - Fatal编程技术网

Java 为什么BigDecimal在四舍五入后返回这个值?

Java 为什么BigDecimal在四舍五入后返回这个值?,java,double,bigdecimal,Java,Double,Bigdecimal,为什么BigDecimal在将期望值四舍五入后返回这个值,而不是期望值,我如何才能达到这个值 // EXPECTED 0.45 // RETURNS 0.45 System.out.println(BigDecimal.valueOf(Double.parseDouble("0.45")) .setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()); // EXPECTED 0.45

为什么
BigDecimal
在将期望值四舍五入后返回这个值,而不是期望值,我如何才能达到这个值

// EXPECTED 0.45
// RETURNS 0.45
System.out.println(BigDecimal.valueOf(Double.parseDouble("0.45"))
                             .setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());

// EXPECTED 0.45
// RETURNS 0.45
System.out.println(BigDecimal.valueOf(Double.parseDouble("0.445"))
                             .setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());

// EXPECTED 0.45
// RETURNS 0.44
System.out.println(BigDecimal.valueOf(Double.parseDouble("0.4445"))
                             .setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());

这是对字面问题的回答

为什么BigDecimal在取整到一半后返回此值 我如何才能达到预期值

// EXPECTED 0.45
// RETURNS 0.45
System.out.println(BigDecimal.valueOf(Double.parseDouble("0.45"))
                             .setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());

// EXPECTED 0.45
// RETURNS 0.45
System.out.println(BigDecimal.valueOf(Double.parseDouble("0.445"))
                             .setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());

// EXPECTED 0.45
// RETURNS 0.44
System.out.println(BigDecimal.valueOf(Double.parseDouble("0.4445"))
                             .setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
应用于0.4445,四舍五入为0.44,而不是“预期”0.45

定义为

舍入模式向“最近邻”舍入,除非两者都有 邻居之间的距离是相等的,在这种情况下,他们会聚集在一起

两个相邻的比例因子分别为0.44和0.45。0.4445和0.44之间的绝对差值为0.0045。0.4445和0.45之间的绝对差值为0.0055。邻域不是等距的,0.44是最近的邻域


如果您真的非常想要一个奇怪的、不必要的不精确取整模式,请使用BigDecimal的toString方法来获取完整的字符串表示。然后,您可以使用字符串操作以任何方式对其进行修改。

round(0.4445)=0.44就可以了。为什么0.4445应该变成0.45?0.44比0.45更接近0.4445。舍入操作是对第一个丢弃的分数进行的,而不是递归地对每个丢弃的分数进行。我猜你希望四舍五入为0.445->0.445->0.45。但正如其他人已经指出的那样,这实际上会给你带来可怕的结果。没有一种内置的舍入模式可以满足你的要求。你想做的在数学上是不正确的(或者至少不是通常的做法)。我建议你考虑一下,如果你真的想按照你在问题中描述的方式进行取整,或者按照其他地方通常采用的方式进行取整不是更好的解决方案……我认为你需要回到一个水平,询问是什么促使你想要这种奇怪的、不必要的不精确的舍入模式。使用字符串是一种可能。或者,他可以反复使用
setScale()
,从高位开始,降低刻度,直到达到目标刻度。这将给出
0.4445->0.445->0.45
@RudyVelthuis是的,这将适用于这种特殊情况。但是,下次OP想要强制打印不正确的double作为目标值时,可能需要进行不同的操作。字符串方法更灵活。是的,当然用字符串初始化的double初始化BigDecimal从来都不是一个好主意。但我认为同样的操作也是必要的。@RudyVelthuis有一些双精度相关的计算,最好用BigDecimal完成,不管双精度的值来自何处。