我很惊讶地看到Java中的以下差异:
(double)(int1/int2) // return 0.0 - precision lost.
(double)int1/int2 // return 9.3123325E-10 - precision kept.
第一个表达式中的括号是否会使评估失去精度?
答案 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