BigDecimal操作精度溢出

时间:2014-11-05 18:29:55

标签: java math bigdecimal

import java.math.BigDecimal;

public class TestNumber {

    public static void main(String[] args) {
        BigDecimal bd = new BigDecimal(0);
        bd = bd.add(new BigDecimal(19.89));
        System.out.println(bd.doubleValue() + " - \t " + bd);
    }
}

我有多个BidDecimals字段和算术运算/比较,问题在于算术结果和小数值。

对于上面的例子,输出如下:

19.89 -      19.8900000000000005684341886080801486968994140625

我希望:

19.89

意外结果会在字段类型BigDecimal

上创建其他不需要的输出

3 个答案:

答案 0 :(得分:3)

使用接受BigDecimal值的double构造函数后,精度已经丢失。您看到的值是该数字的真正IEEE 754表示。你可以使用

bd = bd.add(new BigDecimal("19.89"));

答案 1 :(得分:1)

println显示的double值与该double变量中存储的实际值不同。

在任何范围内都存在无数个实数,但只有有限数量的可表示浮点值。定义浮点值时,该值可能不会映射到可表示的浮点值,在这种情况下,您将获得最接近所需值的可表示值。 (还要记住表示是二进制的,我们熟悉的很多数字都会变成二进制的重复小数,必须被截断。)这里当然只有0.0000000000000005684341886080801486968994140625。

double d = 19.89d;
System.out.println(d);

将向您显示清除d中的内容。 Java正在隐藏乱七八糟的尾随小数。

另一方面,这些行

double d = 19.89d
BigDecimal b = new BigDecimal(d);
System.out.println(b);

导致BigDecimal被d的全部内容初始化,BigDecimal忠实地再现到最后一个尾随数字。

当println传递给BigDecimal时,BigDecimal的toString方法返回一个字符串,显示它存储的数字,println将该字符串写入控制台。

使用

BigDecimal b = new BigDecimal("19.89");

将导致实际十进制值19.89存储在BigDecimal中,因为不涉及浮点评估。

答案 2 :(得分:0)

如果你有一个double并且你需要制作一个BigDecimal而不添加所有额外的精度,请尝试类似

的内容
double d = 19.89; // or something else
bd = new BigDecimal(d, new MathContext(15));

这告诉它只保留15位精度(大约是double支持的精度位数)。这会创建BigDecimal,其toString()返回

"19.8900000000000"

这并不完美,因为所有尾随的零都会显示出来,但它并没有为您提供额外的非零数字。