“possible loss of precision” is Java going crazy or I'm missing something?

这一生的挚爱 提交于 2019-12-22 08:59:28

问题


I'm getting a "loss of precision" error when there should be none, AFAIK.

this is an instance variable:

byte move=0;

this happens in a method of this class:

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

move is a byte, move is still a byte, and the rest is being cast to a byte.

I get this error:

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

I've tried many variations but I still get the same error.

I'm now clueless.


回答1:


Actually all logic operatos (& | ^) return an int, regardless of their operands. You have to cast the final result of x|y as well.




回答2:


That's because this.move<<4 returns an int.

When Java finds a shift operator it applies unary promotion to each operand; in this case, both operands are promoted to int, and so is the result. The behaviour is similar for other Java operators; see a related and instructive discussion, "Varying behavior for possible loss of precision".




回答3:


The bitwise OR operands are subject to Binary Numeric Promotion. Here is how its' defined in 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.

As you can see, there is no byte type so all the bytes are promoted to int by default. You have to cast it back to byte to get rid of the warning,

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


来源:https://stackoverflow.com/questions/2799084/possible-loss-of-precision-is-java-going-crazy-or-im-missing-something

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!