Java - bit shifting with integers and bytes

烈酒焚心 提交于 2019-12-19 04:42:21

问题


Consider the following code (where byteIndex is an int):

int bitNumber = b-(8*byteIndex);
bitMask = 0x8>>(byte)bitNumber;

This generates the error

error: possible loss of precision

when compiled (required byte, found int).

The code

int bitNumber = b-(8*byteIndex);
bitMask = 0x8>>2;

compiles fine.

What is the problem here and how do I fix the first example to allow bit shifting by the int value?

EDIT: Following the comments, here is a more-complete example:

48) int byteIndex;
49) byte bitMask;
50) int bitNumber;
    // assign value to byteIndex
67) bitNumber = b-(8*byteIndex);
68) bitMask = 0x8>>bitNumber;

and the error given is:

...MyClass.java:68: error: possible loss of precision
    bitMask = 0x8>>bitNumber;
             ^
  required: byte
  found:    int
1 error

回答1:


Convert your shifting line to this: -

byte bitMask = (byte)(0x8>>(byte)bitNumber);

Your RHS, is an int, you need to typecast it to byte..

Above code will work fine.. With or without the casting of bitNumber to byte

So, you can also have : -

byte bitMask = (byte)(0x8>>bitNumber);

But, here's is a question - byte bitMask = 0x8>>3; works fine.. Why is it so??

Here's some example to explain the reason behind its working and also the behaviour with final: -

byte bitMask;
int varInt1 = 3;
final int finalVarInt2 = 3;
final int finalVarInt3 = 4;

bitMask = 0x8>>varInt1;    // 1. Will not work. 
bitMask = 0x8<<3;          // 2. Will work

bitMask = 0x8<<4;          // 3. Will not work
bitMask = 0x8<<finalVarInt2;   // 1. Will work
bitMask = 0x8<<finalVarInt3;   // 2. Will not work

Here's some reasoning that explains the above behaviour: -

  • The value on the RHS will be typecasted implicitly only if, the compiler is sure that, it will be able to accomodate that value in the byte variable on LHS.. Else, we have to do Explicit type casting to tell compiler that, we know what we are doing, just do it for us..

Now lets consider all the cases one-by-one (From the above code (1-3, 1-2): -

  1. varInt1 initially contains 3. So the value of RHS evaluates to 64. Although this value might get accomodated to byte variable in LHS, but compiler also knows that, it is possible to change the value of varInt1.. So what if value of varInt1 is changed to 4 at some stage.. It won't work then.. That's why it is not allowed..
  2. Now, in this case, since we have explicitly used an Integer Literal here, so compiler is sure that it will accomodate in byte.. So it allows the implicit casting..
  3. Again, in this case, it is known that RHS will evaluate to 128 which can't be accomodated in byte.. Failed again..

Last two cases are different from regular variables... Since they are declared final, they can't be re-initialized.. So, compiler can make a decision based on the assigned value..

  1. In this case, compiler sees that, finalVarInt2 contains value 3. So, RHS evaluates to 64, which can be accommodated in the byte variable on LHS. Now, since the variable is final it can't be changed, and Compiler knows that, so it is sure that t*his value will always be 64*.. So compiler allows this.

  2. In the last case, value of finalVarInt3 is 4.. Similar reasoning.. Won't fit in LHS, as RHS evaluates to 128 which can't fit into byte




回答2:


In your first example, bitnumber is an int (32 bits), and when you cast it as a byte (8 bits), you are losing the high order 24 bits. Therefore you are losing precision. Just leave the cast (byte) off.




回答3:


In fact this is not the answer, the correct answer is the one Rohit Jain wrote, but this is first time I saw such behavior of JVM, compare these codes:

version where bitNumber is marked as final

final int bitNumber = 10;
final byte bitMask = 0x8 >> bitNumber;

version where bitNumber is not final

int bitNumber = 10;
bitNumber = 10;
final byte bitMask = 0x8 >> bitNumber;

And there is error is second example, probably some optimization. It would be great if someone knows the reason ;-)



来源:https://stackoverflow.com/questions/12639471/java-bit-shifting-with-integers-and-bytes

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