问题
I'm creating a mask and setting higher bits in a short like this:
enum FLAGS {FLAG1, FLAG2, FLAG3, FLAG4, FLAG5, FLAG6};
public static void setFlag(short len, FLAGS flag) {
short mask = 1 << (Short.SIZE - flag.ordinal() - 1);
len |= mask;
}
I printed the values:
len: 0000001111111100
mask : 1000000000000000
after OR'ing with mask: 11111111111111111000001111111100
I understand that when we do bit manipulation on shorts they're upgrded to int to avoid overflow, but why are all the higher bits set then? How can I simply set any of the first 6 bits without any funny casting?
回答1:
short
is signed, and your mask is negative. That is preserved when it is widened to int
. You can make the higher bits zero by masking the mask:
len |= (mask & 0xffff);
Now, that would be if len
was an int
or long
, but since it is short it won't have those higher bits anyway. So really the widening is happening in some other part of your code.
回答2:
It looks like you're OR'ing not AND'ing. '|' is or, '&' is and. Also you're OR'ing a short and an int, not a short and a short. Your print statement even says OR'ing, whereas your title says AND'ing. If you use '&=' I believe it will solve your problem.
回答3:
When the short
is converted to an int
, its numeric value is preserved. If the highest bit is 1, the short
is a negative number, and to preserve its value, the int
would have to be negative - that is, the highest bit of the int
would have to be 1 also, and so would all the bits in between.
In general, when converting a short
to an int
, negative numbers are left-padded with 1s and positive numbers are left-padded with 0s.
回答4:
Just cast the result back to short. You're getting sign-extension in the int
result, because bit 0x8000
is set in the mask, which is the sign bit.
when we do bit manipulation on shorts they're upgrded to int to avoid overflow,
No. No overflow is possible, so that can't be the reason. The reason is for consistency with other operations which can overflow, i.e. +,-,*,/.
来源:https://stackoverflow.com/questions/19101177/java-on-anding-a-short-with-an-short-it-is-upgraded-to-int-and-returns-weird-v