Search code examples
javaandroidtypesunsigned

Convert char[] to byte[] without losing 'bits'


I'm developing an Android 2.3.3 application with Java.

This app is an iOS code with unsigned data types port to Java.

On iOS it works with UInt16 and UInt8. In one case instead using byte[] I'm using char[].

But know I have to send that char[] as a byte[] using a DatagramPacket.

If one element of char[] is 128, how can I do to insert into byte[] and the receiver gets 128. I don't know what happens if I do this:

char c = (char)128;
byte b = (byte)c;

Which will be b value?
128 = 10000000. b = -1 or b = 127?

How can I convert char[] to byte[] without losing any bits?


Solution

  • In Java char is an unsigned 16-bit quantity. So you can directly convert your uint16 to char without doing anything else.

    For unsigned 8-bit quantity you have 2 options:

    1. Use byte. It also holds 8 bits. You don't lose any bits just because it is signed. However, if you do arithmetic with it you need to remember that Java will scale byte up automatically to an int and sign-extend it. To prevent this just always mask it like this:

      byte b; int foo = 5 * (b & 0xFF);

    2. Use char. It is unsigned and can hold 16 bits so the 8 bits will fit in there quite nicely. To put a byte into a char just do this:

      byte b; char c = (char)(b & 0xFF); // Mask off the low-order 8 bits

    To put a char into a byte just do:

    char c;
    byte b = (byte)c; // Truncates to 8 bits
    

    Be aware that byte in Java is signed, so that whenever you do arithmetic with it you need to mask the low-order 8 bits only (to prevent sign-extension). Like this:

    byte b;
    int foo = (b & 0xFF);
    

    You can do all the normal bitwise operations you want with a byte without having to mask:

    byte b;
    if (b & 0x80) ... // Test a flag
    b |= 0x40; // Set a flag
    b ^= 0x20; // Flip a flag from 0 to 1 or 1 to 0
    b ^= ~0x10; // Clear a flag
    byte x = b << 3; // Shift left 3 bits and assign
    byte x = b >>> 4; // Shift right 4 bits and assign (WITHOUT sign extension)