views:

433

answers:

3

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.

+6  A: 

That's because this.move<<4 returns an int. See explanation and some examples here.

leonbloy
+5  A: 

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

Eyal Schneider
oh! Thanks! (to leonbloy and ZZ too)
Lo'oris
+3  A: 

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));
ZZ Coder