为什么Java中的双重拼接会丢失精度?

时间:2015-10-18 18:50:58

标签: java

我很惊讶地看到Java中的以下差异:

 (double)(int1/int2)  // return 0.0 - precision lost.

 (double)int1/int2    // return 9.3123325E-10 - precision kept.

第一个表达式中的括号是否会使评估失去精度?

6 个答案:

答案 0 :(得分:2)

是的,它是设计的。通过将表达式放在parens中,您将修改正常优先级,因此int1/int2将首先执行,并且因为两者都是(推测)整数,所以使用整数除法,这会将结果截断为整数。在第二种情况下,正常优先级适用,因此int1首先被转换为double,然后使用浮点除法完成除法。

答案 1 :(得分:2)

这是order-of-operations的问题。括号的优先级高于强制转换,因此您的第一个语句将首先在括号中执行操作 - 它将商数转换为double

强制转换的优先级高于除法,因此在第二个语句中,强制转换在除法运算之前应用

答案 2 :(得分:1)

由于括号(double)(int1/int2)首先执行整数除法(精确丢失),然后将结果转换为 double

(double)int1/int2执行双重除法,因为第一个操作数是 double

答案 3 :(得分:1)

绝对。在声明1中,您进行除法,然后进行投射。在语句2中,您首先将int1转换为double,然后执行除法,将int2提升为double并保持精度。

我不打算听起来很讽刺,但语言(和编译器)正在按照你的要求去做。 :)

答案 4 :(得分:0)

在第一个中,你进行整数除法,然后进行加倍。由于整数除法会截断任何小数,因此您将丢失答案的小数位,并将其强制转换为双倍并不会使该信息恢复。

在第二个中,你将顶部的一个加倍,然后进行双重划分。这使得答案自动加倍,因为它在分割时需要更高精度的单位,并确保您也获得了小数位。

第二个等同于((double) int1) / int2,因为强制转换的优先级高于/

答案 5 :(得分:0)

我认为这与括号(每个PEMDAS)导致计算在转换发生之前在括号内发生的事实有关,因此,如果除法小于1,则十进制值为0.

示例:

(double)(3/5)=(double)0; (因为Int不能.6)

但是(双倍)3/5 - > (双).6