"可能会失去精确度"是Java疯了还是我错过了什么?

o0'*_*0'. 4 java precision casting

当没有AFAIK时,我会出现"精度损失"错误.

这是一个实例变量:

byte move=0;
Run Code Online (Sandbox Code Playgroud)

这发生在这个类的方法中:

this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF);
Run Code Online (Sandbox Code Playgroud)

move是一个字节,move仍然是一个字节,其余的被转换为一个字节.

我收到此错误:

[javac] /Users/looris/Sviluppo/dumdedum/client/src/net/looris/android/toutry/Guy.java:245: possible loss of precision
[javac] found   : int
[javac] required: byte
[javac]             this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF);
[javac]                                         ^
Run Code Online (Sandbox Code Playgroud)

我尝试了很多变化,但我仍然得到同样的错误.

我现在无能为力.

leo*_*loy 8

那是因为this.move<<4返回一个int.

当Java找到一个移位运算符时,它将 一元促销应用于每个操作数; 在这种情况下,两个操作数都被提升为int,结果也是如此.其他Java运算符的行为类似; 看到一个相关的,有启发性的讨论," 可能导致精度损失的不同行为 ".


Eya*_*der 8

实际上,无论操作数如何,所有逻辑运算符(&| ^)都返回一个int.你必须投射x | y的最终结果.


ZZ *_*der 5

按位OR操作数受二进制数字促销的约束.以下是它在JLS中的定义,

5.6.2二进制数字促销

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示数值类型的值,以下规则按顺序应用,使用扩展转换(第5.1.2节)根据需要转换操作数:

  • 如果任一操作数的类型为double,则另一个操作数转换为double.
  • 否则,如果任一操作数的类型为float,则另一个操作数转换为float.
  • 否则,如果任一操作数的类型为long,则另一个操作数
    转换为long.
  • 否则,两个操作数都将转换为int类型.

如您所见,没有字节类型,因此默认情况下所有字节都被提升为int.你必须将其强制转换为字节以消除警告,

this.move=(byte)((this.move<<4)|(Guy.moven.indexOf("left")&0xF));
Run Code Online (Sandbox Code Playgroud)