0

在Java中,如果变量也是浮点数,则否定变量与将变量乘以浮点数减一之间有区别吗?

4

4 回答 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)结果是一个floadfmul,这可能会稍微慢一些。

我不知道 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 回答