Reputation: 45931
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?
Upvotes: 1
Views: 6371
Reputation: 95588
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:
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);
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)
Upvotes: 8
Reputation: 1074666
I think you need to rethink your approach so you don't end up needing to convert char[]
to byte[]
.
If your data really is characters, then you want to look at various serialization techniques, such as using new String(char[])
to create a string and then using getBytes(Charset)
to get the bytes as encoded by a given Charset
(because, of course, the same characters result in different bytes when encoded in ASCII or UTF-8 or UTF-16, etc.).
But from your question, it sounds like you're not really using characters, you're just using char
as a 16-bit type. If so, doing the conversion isn't difficult, something along these lines:
byte[] toBytes(char[] chars) {
byte[] bytes = new byte[chars.length * 2];
int ci, bi;
char ch;
bi = 0;
for (ci = 0; ci < chars.length; ++ci) {
ch = chars[ci];
bytes[bi++] = (byte)((ch & 0xFF00) >> 8);
bytes[bi++] = (byte)(ch & 0x00FF);
}
return bytes;
}
Reverse the masks if you want the result to be small-endian instead.
But again, I would look at your overall approach and try to avoid this.
Upvotes: 2