-x与x * -1.0f之间有区别吗?

时间:2016-04-25 12:45:27

标签: java floating-point negate

在java中,如果变量也是一个浮点数,那么否定一个变量与一个浮点数乘以一个变量之间是否存在差异?

4 个答案:

答案 0 :(得分:2)

Java使用IEEE的二进制浮点表示,其中符号由单独的位表示。两者都乘以-1并将符号与-x反转是通过翻转此符号位来完成的,同时保持表示的其余部分不变。这就是为什么结果没有差异,因为-1.0f具有精确的表示,并且没有机会改变x的表示精度。

答案 1 :(得分: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)会产生floadfmul,这可能会稍慢。

我不知道JIT编译器是否会优化它。

为了便于阅读,使用-x通常会更好。

答案 2 :(得分: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优化)。

答案 3 :(得分:0)

如果x已经是float,则没有区别。但是-x更具可读性。