Java integer to fixed length byte array - java

How can I convert an integer between 0 and 65k to fixed length of two bytes? as an example
2 would be 00000000 00000010
~65k would be 11111111 11111111
and all that in a byte array

java has the short data type, this is a 2 bytes integer. You cast the integer to short.
int a = 1;
short b = (short)a;
If you want the bytes of the integer you can use ByteBuffer
byte[] bytes = ByteBuffer.allocate(2).putShort((short)intnumber).array();
Or if you want the binary format you can just use toBinaryString method of the Integer.
int x = 2;
System.out.println(Integer.toBinaryString(x));

When x is your number between 0 and 65,535 just use
new byte[] { (byte) (x >> 8), (byte) x }
to create a byte array containing the value as two bytes in big-endian format.

Related

integer to byte in Java and C++

In my C++ code, I need to convert an int and put it inside a byte. I represent a byte using a char.
In my java code, I should read this byte (it is sent over the network), and I should get the appropriate int from that byte (the one that I sent).
I should mention that this byte is less than 15, so one byte would be sufficient for it
However, the Java code is reading negative numbers in some attempts, and when I tried other ways it gave me totally different numbers. I suspect it is a problem of big/little endian.
What I've tried:
// C++
char bytes[255];
bytes[0] = myInt; // attempt 1
bytes[0] = myInt & 0xFF; // attempt 2
// ... send the byte array over the network
// JAVA
// receive the byte
int readInt = bytes[0]; //attempt 1
int readInt = bytes[0] & 0xFF; // attempt2
How should I properly do this, given that the two applications (C++ side and JAVA side) will run on the same ubuntu machine?
Note: it's never an endian issue. Only if you work low level or make your own arrays of bytes to represent one number, it may be an endian issue.
It is only one byte now, so no endian issue.
Try to use unsigned int.
Further edit: int readInt = bytes[0] & 0xFF should work.
for (int i = 0; i < 256; i++) {
byte b = (byte) i;
int j = b & 0xFF;
System.out.println("The byte is " + b + " and the int is " + j);
}
Gives:
The byte is 0 and the int is 0
The byte is 1 and the int is 1
...
The byte is 126 and the int is 126
The byte is 127 and the int is 127
The byte is -128 and the int is 128
The byte is -127 and the int is 129
...
The byte is -2 and the int is 254
The byte is -1 and the int is 255
Edit (after comment above): 7 = 0000 0111 and -32 = 1110 0000 (= 224 as int) The issue appears to be some kind of mirroring flip.
and 170 = 1010 1010 (= -86 as Java byte) which doesn't make sense to me because how did 3 on bits turn into 4 and spread out.

Can't convert byte to normal view

I have long value, which i want to convert ot byte array. I use this function
public static byte[] longToByteArray(long value) {
byte[] result = new byte[8];
for(int i = 0; i < 8; i++) {
result[i] = (byte)(value & 0xFF);
System.out.println(result[i]);
System.out.println(Integer.toBinaryString(result[i]));
value >>>= 8;
}
return result;
}
and output data looks like
18
10010
-12
11111111111111111111111111110100
88
1011000
83
1010011
0
0
0
0
0
0
0
0
Why i have too much 1 in binary view of -12, and how can i get it like
11110100
That's because Integer.toBinaryString(result[i]) converts your byte to int (32 bits), and also, bytes are represented from -128 to 127, so values grater than 127 are being represented as negative numbers; hence, your byte ends up being a negative int. to solve it you can change this line:
System.out.println(Integer.toBinaryString(result[i]));
for this one:
System.out.println(Integer.toBinaryString(result[i] & 0xFF));
Your -12 is coming out as 11111111111111111111111111110100 because it is a negative number encoded in 2's complement format using all 32-bits available to it as it is being parsed as an integer.
If you only want the final 8 bits, you'll probably have to format it like that. Check this answer: How to convert a byte to its binary string representation
The reason is that even though you do (byte)(value & 0xFF) when you call Integer.toBinaryString it is being converted back to a 32 bit integer and you are getting proper output for -12 integer.
One simple solution is to convert negative byte values (-128 to -1) to be positive unsigned byte values (128 to 255). This is done simply by testing for negative and adding 256, like such:
int b = (int)(value & 0xFF);
if (b<0) {
b = b + 256;
}
This is done in an integer data type, but the resulting value is 0..255 which is appropriate for an unsigned byte. So now, it turns out, instead of -12 you will have 244 but it turns out that the binary representation of 244 is the same as an 8-bit version of -12. Try it out!
you can use JBBP
byte [] packed = JBBPOut.BeginBin().Long(aLongValue).End().toByteArray();

Extract certain byte from char array and byte array in java

I have an char array containing hex value. It contains 6 bytes. I have calculated the crc of these 6 bytes and the function returns int value.
This is the code.
char buffer[] = {0x01,0x05,0x00,0x06,0x00,0x00};
byte[] bufferbyte = new String(buffer).getBytes();
for (byte bb : bufferbyte){
System.out.format("0X%x ", bb);
}
int crcresult;
crcresult = CRC16(buffer,6); //crc calculation
byte[] crc_bytes = ByteBuffer.allocate(4).putInt(crcresult).array();
for (byte b : crc_bytes){
System.out.format("0X%x ", b);
}
My question are
I have used bytebuffer to convert crc obtained as int into byte. But the calculated crc are stored in 4 byte instead of 2 byte. I have calculated CRC 16 but the resulting crc is 32 bit . I think it is because i have returned "int" in the crc calculation and it is written that in java an int is 32 bits.
So How to extract only two bytes from the byte buffer (crc_bytes) or the calculated int crc (crcresult).
I have put the bytes of the "char buffer[]" and two bytes of calculated crc in single byte array. How can we append
char buffer[] and crcresult
in one byte array.
The output of above code is
0X1 0X5 0X0 0X6 0X0 0X0 0X0 0X0 0X2d 0Xcb
Where first 6 bytes are bytes converted from char array and last 4 bytes are crc.
The two bytes of the crc in big endian order can be fetched with
byte[] crc_result = new byte[2];
crc_bytes[0] = (byte)(crcresult >> 8); // this are the high order 8 bits
crc_bytes[1] = (byte)crcresult; // this are the low order 8 bits
If you need it in little endian order just adapt the assignments accordingly.
It is not clear to me why you use a char array to represent bytes.
Yes, crcresult is 32 bits because it is of type int. If you want a 16bit data type, use short instead.
But, using int type does not do any harm. Although it is 32 bit, only last 16 bits will contain CRC16 value. You can extract those two bytes with following bitwise operations.
byte byte1 = (byte)((crcresult >> 8) & 0xFF); // first 8 bits of last 16 bits
byte byte0 = (byte)(crcresult & 0xFF); // last 8 bits
To merge the results.
byte[] merged = new byte[bufferbyte.length + 2];
System.arrayCopy(bufferbyte, 0, merged, 0, bufferbyte.length); // copy original data buffer
merged[bufferbyte.length ] = byte1; // append crc16 byte 1
merged[bufferbyte.length + 1] = byte0; // append crc16 byte 2
Refer System.arrayCopy for more details.

Converting integer variable to byte variable

Hello i'm learning java programming and i just had task in my book which says to convert
int varible to byte variable
byte b;
int i=257;
And when i convert int to b
b=(byte) i;
Output is 1 ?
How it can be one when value of byte variable goes from -128 to 127
In my book they say byte variable have range of validity to 256 ?
257 == 00000000000000000000000100000001 (as integer which holds 32 bits)
1 == 00000001 (byte holds only 8 bits)
Because it can store any number from -128 to 127. A byte is always signed in Java. You may get its unsigned value by binary-anding it with 0xFF.
Example:
int i = 234;
byte b = (byte) i;
System.out.println(b); // -22
int i2 = b & 0xFF;
System.out.println(i2); // 234
The key here is to look at the bits.
int i = 257 gives us this set of bits (leaving off leading zeros):
b100000001
That value requires nine bits to hold (int has 32, so plenty of room). When you do b = (byte)i, it's a truncating cast. That means only what can be held by the byte (eight bits) is copied to it. So that gives us the lower eight bits:
b00000001
...which is the value 1.
The range of 256 is because it can store any number from -128 all the way to 127. The difference between these two numbers is 256. The value of 1 has occurred thanks to overflow, where you've attempted to store a value that can not be accurately represented with 7 bits and 1 sign bit.
its because byte range is from -128 to +127
Please check this link why byte is from -128 to 127
-128 0 127, So range is 256.
-2^7 to 2^7-1

How to convert binary string to the byte array of 2 bytes in java

I have binary string String A = "1000000110101110". I want to convert this string into byte array of length 2 in java
I have taken the help of this link
I have tried to convert it into byte by various ways
I have converted that string into decimal first and then apply the code to store into the byte array
int aInt = Integer.parseInt(A, 2);
byte[] xByte = new byte[2];
xByte[0] = (byte) ((aInt >> 8) & 0XFF);
xByte[1] = (byte) (aInt & 0XFF);
System.arraycopy(xByte, 0, record, 0,
xByte.length);
But the values get store into the byte array are negative
xByte[0] :-127
xByte[1] :-82
Which are wrong values.
2.I have also tried using
byte[] xByte = ByteBuffer.allocate(2).order(ByteOrder.BIG_ENDIAN).putInt(aInt).array();
But it throws the exception at the above line like
java.nio.Buffer.nextPutIndex(Buffer.java:519) at
java.nio.HeapByteBuffer.putInt(HeapByteBuffer.java:366) at
org.com.app.convert.generateTemplate(convert.java:266)
What should i do now to convert the binary string to byte array of 2 bytes?Is there any inbuilt function in java to get the byte array
The answer you are getting
xByte[0] :-127
xByte[1] :-82
is right.
This is called 2's compliment Represantation.
1st bit is used as signed bit.
0 for +ve
1 for -ve
if 1st bit is 0 than it calculates as regular.
but if 1st bit is 1 than it deduct the values of 7 bit from 128 and what ever the answer is presented in -ve form.
In your case
1st value is10000001
so 1(1st bit) for -ve and 128 - 1(last seven bits) = 127
so value is -127
For more detail read 2's complement representation.
Use putShort for putting a two byte value. int has four bytes.
// big endian is the default order
byte[] xByte = ByteBuffer.allocate(2).putShort((short)aInt).array();
By the way, your first attempt is perfect. You can’t change the negative sign of the bytes as the most significant bit of these bytes is set. That’s always interpreted as negative value.
10000001₂ == -127
10101110₂ == -82
try this
String s = "1000000110101110";
int i = Integer.parseInt(s, 2);
byte[] a = {(byte) ( i >> 8), (byte) i};
System.out.println(Arrays.toString(a));
System.out.print(Integer.toBinaryString(0xFF & a[0]) + " " + Integer.toBinaryString(0xFF & a[1]));
output
[-127, -82]
10000001 10101110
that is -127 == 0xb10000001 and -82 == 0xb10101110
Bytes are signed 8 bit integers. As such your result is completely correct.
That is: 01111111 is 127, but 10000000 is -128. If you want to get numbers in 0-255 range you need to use a bigger variable type like short.
You can print byte as unsigned like this:
public static String toString(byte b) {
return String.valueOf(((short)b) & 0xFF);
}

Categories

Resources