1

Related question : Java On AND'ing a short with an short, it is upgraded to int and returns weird values

I have a short (2 bytes) space which should be used for setting 16 flags, one in each bit. I have to write an API to set/check/clear n'th bit (n = 0, 1..15). The problem comes in case of the MSBit.

I'm setting it like this:

 short setBit(short flags, int n) {
     flags |= (1 << n);
     return flags;
 }      

When n is 15 I set the sign bit and resulting value is : 1111111111111111111111111111111111111111111111111000000000000000.

I tried to fetch the lower 16 bits out of this by doing :

            flags &= 0xffff;

I get the same answer which is expected as the sign bit remains the same. How do I set the highest bit and don't end up converting type and having sign bit extend/fill rest of the space? (These flags are to be written to the disk).

Community
  • 1
  • 1
user1071840
  • 3,522
  • 9
  • 48
  • 74

2 Answers2

1

Your problem stems from Java's implicit type promotion system.

To counteract Java's "helpful" type promotions, judicious type casting is in order...

short setBit(short flags, int n) {
  return (short)( flags | (short)(1 << n));
}

Also, you can avoid type promotion when printing like so: (prints in hex)

System.out.printf("%x\n",setBit(myShortVariable,15));
recursion.ninja
  • 5,377
  • 7
  • 46
  • 78
0

Use a char instead of a short.
See: unsigned short in java

 char setBit(char flags, int n) {
     if (n <= 15) {
       char bit = (1 << n); 
       flags |= bit;
     }
     return flags;
 }  
Community
  • 1
  • 1
Johan
  • 74,508
  • 24
  • 191
  • 319
  • Not according to jon skeet, but I guess you know better. – Johan Oct 06 '13 at 12:50
  • Jon and I agree: "Admittedly you could use char - it's a 16-bit unsigned type - but that would be horrible, as char is clearly meant to be for text." http://stackoverflow.com/questions/1841461/unsigned-short-in-java/1841471#1841471 – starblue Oct 07 '13 at 17:58
  • I like this comment better:`There seems to be no way in Java to have a normal machine‐level byte, meaning an 8‑bit location that can hold values [0–255] instead of [ −128 – +127 ]. I can’t believe they make us use signed bytes, when all you have to do in C is say unsigned char. Once you start down the road of signed datatypes only, it screws up all your unsigned bitmaps. Really quite unpleasant. The Java designers thought they were simplifying things to make them less error‐prone, but once again all they managed to do was make them a lot harder and more error‐prone than before.` – Johan Oct 07 '13 at 19:42
  • @starblue, so how do **you** set the highest bit? – Johan Oct 07 '13 at 19:45
  • For setting the highest bit it doesn't matter whether `short` is signed or unsigned: http://stackoverflow.com/questions/397867/port-of-random-generator-from-c-to-java/397997#397997 – starblue Oct 07 '13 at 19:53