Java BigDecimal运算精度溢出

Java BigDecimal运算精度溢出,java,math,bigdecimal,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.

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

对于上述示例,输出如下所示:

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);
    }
}
我期望:

19.89


意外结果会创建其他不需要的输出,以对字段类型BigDecimal执行操作。一旦使用接受双值的BigDecimal构造函数,精度已经丢失。您看到的值是该数字的真实IEEE 754表示形式。你可以用

19.89 -      19.8900000000000005684341886080801486968994140625

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

19.89 -      19.8900000000000005684341886080801486968994140625

println显示的双精度值与该双精度变量中存储的实际值不同

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

台词

bd = bd.add(new BigDecimal("19.89"));
将向您显示d中的近似值。Java正在向您隐藏混乱的尾随小数

另一方面,这些线

double d = 19.89d;
System.out.println(d);
结果BigDecimal使用d的全部内容进行初始化,BigDecimal会忠实地复制到最后一个尾随数字

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

使用

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

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

println显示的双精度值与该双精度变量中存储的实际值不同

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

台词

bd = bd.add(new BigDecimal("19.89"));
将向您显示d中的近似值。Java正在向您隐藏混乱的尾随小数

另一方面,这些线

double d = 19.89d;
System.out.println(d);
结果BigDecimal使用d的全部内容进行初始化,BigDecimal会忠实地复制到最后一个尾随数字

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

使用

double d = 19.89d
BigDecimal b = new BigDecimal(d);
System.out.println(b);
将导致实际十进制值19.89存储在BigDecimal中,因为不涉及浮点计算

如果您有一个double,并且需要从中生成一个BigDecimal,而不需要添加所有额外的精度,请尝试以下操作

BigDecimal b = new BigDecimal("19.89");
这告诉它只保留15位精度,这大约是双精度支持的精度位数。这将创建一个toString返回的BigDecimal

这并不是很完美,因为所有尾随的零都会显示出来,但它不会给你额外的非零数字。

如果你有一个双精度,你需要用它生成一个大十进制,而不增加所有额外的精度,那么试试下面的方法

BigDecimal b = new BigDecimal("19.89");
这告诉它只保留15位精度,这大约是双精度支持的精度位数。这将创建一个toString返回的BigDecimal


这不是很完美,因为所有尾随的零都会显示出来,但它不会给你额外的非零数字。

bigdecimal构造函数不是问题,它准确地传递了双浮点值。转到,输入19.89,然后单击“双精度”。这将解释您获得19.89000000000000056843418860801486968994140625的原因。bigdecimal构造函数不是问题所在,它准确地传递了双浮点值。转到,输入19.89,然后单击double。这将解释为什么您得到19.89000000000000056843418860801486968994140625。