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

时间:2010-05-09 20:36:50

标签: java casting precision

当没有AFAIK时,我会出现“精度损失”错误。

这是一个实例变量:

byte move=0;

这种情况发生在这个类的方法中:

this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF);

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]                                         ^

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

我现在无能为力。

3 个答案:

答案 0 :(得分:8)

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

当Java找到a shift operator时,它会将unary promotion应用于每个操作数;在这种情况下,两个操作数都被提升为int,结果也是如此。 其他Java运算符的行为类似;请参阅相关且富有启发性的讨论,“Varying behavior for possible loss of precision”。

答案 1 :(得分:8)

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

答案 2 :(得分:5)

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

  

5.6.2二进制数字促销

     

当运算符应用二进制时   数字促销到一对   操作数,每个都必须表示一个   数值类型的值,如下   规则适用于使用拓宽的顺序   转换(§5.1.2)进行转换   必要时操作数:

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

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

this.move=(byte)((this.move<<4)|(Guy.moven.indexOf("left")&0xF));