2010-05-09 83 views
4

当应该没有AFAIK时,我收到“精度丢失”错误。“可能的精度损失”是Java发疯了还是我错过了什么?

这是一个实例变量:

byte move=0; 

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

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

举动是一个字节,移动仍是一个字节,其余的是被铸造到一个字节。

我得到这个错误:

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

我已经尝试了许多变化,但我仍然得到同样的错误。

我现在无能为力。

+1

如果移动是128,该怎么办?当您将它移位4位时,会导致精度损失。 “byte << N”定义为返回另一个字节,还是一个int? – 2010-05-09 20:50:17

回答

8

实际上,所有逻辑运算符(& | ^)都会返回一个int,而不考虑它们的操作数。您还必须输出x | y的最终结果。

+0

哦!谢谢! (以leonbloy和ZZ太) – 2010-05-09 21:59:23

8

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

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

+0

该链接对我来说非常有用,但没有关于按位移的示例。有关复合赋值语句的解释。 – CEGRD 2012-11-29 18:57:05

5

按位或操作数都受到二元数值提升。下面是它的如何在JLS定义,

5.6.2 Binary Numeric Promotion

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value of a numeric type, the following rules apply, in order, using widening conversion (§5.1.2) to convert operands as necessary:

  • If either operand is of type double, the other is converted to double.
  • Otherwise, if either operand is of type float, the other is converted to float.
  • Otherwise, if either operand is of type long, the other is
    converted to long.
  • Otherwise, both operands are converted to type int.

正如你所看到的,没有字节类型,因此所有字节提升默认为int。你必须将其转换回字节以摆脱警告,

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

实际上这里对一元数值提升ocurr,而不是二进制看到的http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#5121 – leonbloy 2012-11-29 19:07:09

相关问题