0

I'm trying to extract 6 bytes from a byte array and convert them into a 48 bit signed integer value (I. E. a Java long). How can this be accomplished?

Edit: For example, if a byte array has one of the following:

byte[] minInt48 = new byte[] { (byte)0x80, 0, 0, 0, 0, 0 };
byte[] maxInt48 = new byte[] { (byte)0x7F, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };

How can I parse this into a Java primitive (i.e. Java long) such that the sign value is preserved?

1 Answers1

0

First you need to understand sign extension. You need to treat each byte as an unsigned value.

      long v = 0;
      byte q = -2; // unsigned value of 254
      v = v + q;
      System.out.println(v); // prints -2 which is not what you want.
      v = 0;
      v = v + (q & 0xFF); // mask off sign extension from q.
      System.out.println(v); // prints 254 which is correct.

This is one way of doing it.

     long val = 0;
     byte[] bytes = { -1, 12, 99, -121, -3, 123
     };
     for (int i = 0; i < bytes.length; i++) {
        // shift the val left by 8 bits first.
        // then add b.  You need to mask it with 0xFF to
        // eliminate sign extension to a long which will
        // result in an incorrect conversion.
        val = (val << 8) | ((i == 0 ? bytes[i]
              : bytes[i] & 0xFF));
     }
     System.out.println(val);
WJS
  • 36,363
  • 4
  • 24
  • 39
  • 1
    OP asked for a _signed_ result: Your algorithm gives an unsigned result. One option to fix it would be to treat the first byte specially--don't mask of the sign bits of the first byte. – Solomon Slow Jun 07 '19 at 14:15
  • You are correct! I edited the suggestion. However, there are probably better ways to do it. Thanks! – WJS Jun 07 '19 at 16:10