Java和浮点数
为什么在打印z时会得到不同的结果,如下面的代码段所示Java和浮点数,java,Java,为什么在打印z时会得到不同的结果,如下面的代码段所示 似乎编译器在第二个“打印”中剪切“2”之后的所有位置。。。 谢谢你的帮助 double z = 1.0; z = z + 0.1; z = z + 0.1; System.out.print("z := "+z); System.out.print(" # z:= "+((0.1+0.1)+(1.0))); 输出: z := 1.2000000000000002 # z:= 1.2 z := 1.2 # z:= 1.2 打印z显示的值不
似乎编译器在第二个“打印”中剪切“2”之后的所有位置。。。 谢谢你的帮助
double z = 1.0;
z = z + 0.1;
z = z + 0.1;
System.out.print("z := "+z);
System.out.print(" # z:= "+((0.1+0.1)+(1.0)));
输出:
z := 1.2000000000000002 # z:= 1.2
z := 1.2 # z:= 1.2
打印z
显示的值不同于1.2
,因为将1.0
添加到0.1
两次的结果不能在双精度中精确表示。
System.out.print(" # z:= "+((0.1+0.1)+(1.0)));
这将打印#z:=1.2
,因为编译器将“#z:=”+((0.1+0.1)+(1.0))
视为常量字符串,并在编译代码中直接替换为#z:=1.2
。换句话说,这句话完全等同于:
System.out.print(" # z:= 1.2");
第一个代码是
1.0+0.1
(中间结果是1.1
)+0.1
。
第二个代码是0.1+0.1
(中间结果是0.2
)+1.0
。
由于浮点精度,它不能完美地表示每个数字,因此会得到不同的结果
double z = 1.0;
z = z + 0.1;
System.out.println(z);
z = z + 0.1;
System.out.println(z);
z = 0.1;
z = z + 0.1;
System.out.println(z);
z = z + 1.0;
System.out.println(z);
输出:
1.1
1.2000000000000002
0.2
1.2
请阅读上的详细信息,使用BigDecimal可获得准确的计算结果。像
float
和double
这样的二进制格式可能具有更好的性能,但在将它们转换为十进制数时会导致意外的结果
有些数字不能用二进制精确表示。我们都知道这样的问题,当试图用十进制表示法(0.33333…永无止境)写“三分之一”时
示例代码:
BigDecimal z = new BigDecimal("1.0");
z = z.add(new BigDecimal("0.1"));
z = z.add(new BigDecimal("0.1"));
System.out.print("z := "+z);
System.out.print(" # z:= "+((0.1+0.1)+(1.0)));
输出:
z := 1.2000000000000002 # z:= 1.2
z := 1.2 # z:= 1.2
在线运行代码:为什么将1.0和0.1相加两次不能用双精度表示?@Lrrr因为浮点值是以二进制存储的?@Gosu这个答案的问题是它没有解释主要问题,主要问题正是我强调的部分@重复回答的Lrrr。这个答案指出了两个版本的编译方式的不同,这会影响结果:计算结果与编译器放置的字符串文本。实际上,这不是相同的代码。你应该与1.0+0.1+0.1进行比较