Java BigDecimal行为的差异
我有两段代码Java BigDecimal行为的差异,java,bigdecimal,Java,Bigdecimal,我有两段代码newbigdecimal(“1.240472701”)和newbigdecimal(1.240472701)。现在,如果我在这两种方法上使用java的compareTo方法,那么我会发现它们并不相等 当我使用java的System.out.println()方法打印值时。对于这两个值,我得到了不同的结果。比如说 new BigDecimal("1.240472701") -> 1.240472701 new BigDecimal(1.240472701) -> 1.2
newbigdecimal(“1.240472701”)
和newbigdecimal(1.240472701)
。现在,如果我在这两种方法上使用java的compareTo方法,那么我会发现它们并不相等
当我使用java的System.out.println()方法打印值时。对于这两个值,我得到了不同的结果。比如说
new BigDecimal("1.240472701") -> 1.240472701
new BigDecimal(1.240472701) -> 1.2404727010000000664291519569815136492252349853515625
所以我想了解这可能是什么原因?您可以参考的Java文档:
public BigDecimal(double val)
将双精度转换为大十进制
这是双精度二进制的精确十进制表示形式
浮点值。返回的BigDecimal的小数位数为
使(10^scale×val)为整数的最小值
-
此构造函数的结果可能有些不可预测。一个
可能假设在Java中编写新的BigDecimal(0.1)会创建
BigDecimal正好等于0.1(未标度值为1,带
比例为1),但实际上等于
0.1000000000000000055511151231257827021181583404541015625. 这是因为0.1不能精确地表示为double(或者
物质,作为任何有限长度的二元分数)。因此,价值
传递给构造函数的不完全等于
0.1,尽管有外观
-
另一方面,字符串构造函数是完全可预测的:编写新的BigDecimal(“0.1”)创建
正如人们所期望的,正好等于0.1的大十进制数。
因此,通常建议使用字符串构造函数
用于优先于这个的
-
当必须将双精度计数器用作源时
对于BigDecimal,请注意此构造函数提供了精确的
转化;它不会给出与转换double相同的结果
使用Double.toString(Double)方法,然后使用
BigDecimal(字符串)构造函数。要获得该结果,请使用静态
(双)值法
因为用户thegauravmahawar从文档中提供了答案。是的,这是因为在BigDecimal的情况下进行了缩放。
因此,这些值可能看起来与您相同,但java内部在存储BigDecimal类型的值时使用缩放。
原因:缩放。
改进:
您可以对正在比较的数字调用setScale:
像这样
new BigDecimal ("7.773").setScale(2).equals(new BigDecimal("7.774").setScale (2))
这将避免您犯任何错误。字符串“1.240472701”
是十进制值的文本表示形式。BigDecimal
代码解析该值,并使用字符串中表示的精确值创建一个BigDecimal
但是,double
1.240472701
仅仅是精确十进制值的(接近)近似值Double
无法精确表示所有十进制值,因此存储在Double
中的精确值略有不同。如果您将其传递给一个BigDecimal
,它将接受不同的值并将其转换为一个精确的BigDecimal
。但是BigDecimal
只有不精确的double
,它不知道确切的文本表示。因此,它只能表示double
中的值,而不能表示源文本的值
在第一种情况下:
String --> BigDecimal
因为BigDecimal是用来精确表示十进制值的,所以这种转换是精确的
在第二种情况下:
1 2
Source code text --> double --> BigDecimal
在第二种情况下,精度在第一次转换(1)中丢失。第二个转换(2)是精确的,但输入(双精度)是源代码文本1.240472701
的不精确表示(实际上,它是1.240472701000000066429151956981513649252349853515625
)
所以:如果可以避免的话,千万不要用double来初始化BigDecimal。改为使用字符串
这就是为什么第一个BigDecimal是精确的,而第二个不是。不是每个小数都可以用浮点表示variable@ScaryWombat:我认为与OP有关的是,除了从不同类型创建数字外,还要创建相同的“数字”