在Java中,如果变量也是浮点数,则否定变量与将变量乘以浮点数减一之间有区别吗?
问问题
154 次
4 回答
2
Java 使用 IEEE 的二进制浮点表示,符号由单独的位表示。乘以-1
和反转符号-x
都是通过翻转这个符号位来完成的,同时保持表示的其余部分不变。这就是为什么结果没有差异的原因,因为-1.0f
有一个精确的表示,并且没有机会改变 的表示的精度x
。
于 2016-04-25T12:51:25.190 回答
2
在 JLS §15.15.4 “一元减号运算符 -”中,我们发现
对于浮点值,取反与从零减法不同,因为如果 x 为 +0.0,则 0.0-x 为 +0.0,但 -x 为 -0.0。一元减号只是反转浮点数的符号。感兴趣的特殊情况:
如果操作数为 NaN,则结果为 NaN。(回想一下,NaN 没有符号(§4.2.3)。)
如果操作数是无穷大,则结果是相反符号的无穷大。
如果操作数为零,则结果是相反符号的零。
(突出我的)
可以在发出的字节码中看到差异。一元减号是一个简单的fneg
,而(-1f * x)
结果是一个fload
和fmul
,这可能会稍微慢一些。
我不知道 JIT 编译器是否会优化它。
为了可读性,使用-x
通常更好。
于 2016-04-25T13:02:02.713 回答
1
如果x
已经是 afloat
那么没有区别。但是-x
更具可读性。
于 2016-04-25T12:53:37.383 回答
1
产生的字节码略有不同:
float one(float x) {
return -x;
}
float two(float x) {
return x * -1.f;
}
float three(float x) {
return -1.f * x;
}
反编译为:
float one(float);
Code:
0: fload_1
1: fneg
2: freturn
float two(float);
Code:
0: fload_1
1: ldc #2 // float -1.0f
3: fmul
4: freturn
float three(float);
Code:
0: ldc #2 // float -1.0f
2: fload_1
3: fmul
4: freturn
我想该fneg
指令比fload_1/fmul
;稍快一些。但差异可能可以忽略不计(并且很可能由 JIT 优化)。
于 2016-04-25T12:57:58.293 回答