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();
Related
I have next method for converting to int from hex:
public static byte[] convertsHexStringToByteArray2(String hexString) {
int hexLength = hexString.length() / 2;
byte[] bytes = new byte[hexLength];
for (int i = 0; i < hexLength; i++) {
int hex = Integer.parseInt(hexString.substring(2 * i, 2 * i + 2), 16);
bytes[i] = (byte) hex;
}
return bytes;
}
when I use it for "80" hex string I get strange, not expected result:
public static void main(String[] args) {
System.out.println(Arrays.toString(convertsHexStringToByteArray2("80"))); // gives -128
System.out.println(Integer.toHexString(-128));
System.out.println(Integer.toHexString(128));
}
the output:
[-128]
ffffff80
80
I expect that "80" will be 128. What is wrong with my method?
I have next method for converting to int from hex
The method you posted converts a hex String to a byte array, and not to an int. That's why it is messing with its sign.
Converting from hex to int is easy:
Integer.parseInt("80", 16)
$1 ==> 128
But if you want to get a byte array for further processing by just casting:
(byte) Integer.parseInt("80", 16)
$2 ==> -128
It "changes" its sign. For further information on primitives and signed variable types take a look at Primitive Data Types, where it says:
The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation.
One could easily invert the sign by just increasing the value to convert:
(byte) Integer.parseInt("80", 16) & 0xFF
$3 ==> 128
That gets you a byte with the value you expect. Technically that result isn't correct and you must to switch the sign again, if you want to get an int or a hex string back again. I'd suggest you to don't use a byte array if you only want to convert between hex and dec.
A byte in Java stores numbers from -128 to 127. 80 in hex is 128 as an integer, which is too large to be stored in a byte. So, the value wraps around. Use a different type to store your value (such as a short).
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.
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
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);
}
I know Java doesn't allow unsigned types, so I was wondering how it casts an integer to a byte. Say I have an integer a with a value of 255 and I cast the integer to a byte. Is the value represented in the byte 11111111? In other words, is the value treated more as a signed 8 bit integer, or does it just directly copy the last 8 bits of the integer?
This is called a narrowing primitive conversion. According to the spec:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
So it's the second option you listed (directly copying the last 8 bits).
I am unsure from your question whether or not you are aware of how signed integral values are represented, so just to be safe I'll point out that the byte value 1111 1111 is equal to -1 in the two's complement system (which Java uses).
int i = 255;
byte b = (byte)i;
So the value of be in hex is 0xFF but the decimal value will be -1.
int i = 0xff00;
byte b = (byte)i;
The value of b now is 0x00. This shows that java takes the last byte of the integer. ie. the last 8 bits but this is signed.
or does it just directly copy the last
8 bits of the integer
yes, this is the way this casting works
The following fragment casts an int to a byte. If the integer’s value is larger than the range of a byte, it will be reduced modulo (the remainder of an integer division by the) byte’s range.
int a;
byte b;
// …
b = (byte) a;
Just a thought on what is said: Always mask your integer when converting to bytes with 0xFF (for ints). (Assuming myInt was assigned values from 0 to 255).
e.g.
char myByte = (char)(myInt & 0xFF);
why? if myInt is bigger than 255, just typecasting to byte returns a negative value (2's complement) which you don't want.
Byte is 8 bit. 8 bit can represent 256 numbers.(2 raise to 8=256)
Now first bit is used for sign. [if positive then first bit=0, if negative first bit= 1]
let's say you want to convert integer 1099 to byte. just devide 1099 by 256. remainder is your byte representation of int
examples
1099/256 => remainder= 75
-1099/256 =>remainder=-75
2049/256 => remainder= 1
reason why? look at this image http://i.stack.imgur.com/FYwqr.png
According to my understanding, you meant
Integer i=new Integer(2);
byte b=i; //will not work
final int i=2;
byte b=i; //fine
At last
Byte b=new Byte(2);
int a=b; //fine
for (int i=0; i <= 255; i++) {
byte b = (byte) i; // cast int values 0 to 255 to corresponding byte values
int neg = b; // neg will take on values 0..127, -128, -127, ..., -1
int pos = (int) (b & 0xFF); // pos will take on values 0..255
}
The conversion of a byte that contains a value bigger than 127 (i.e,. values 0x80 through 0xFF) to an int results in sign extension of the high-order bit of the byte value (i.e., bit 0x80). To remove the 'extra' one bits, use x & 0xFF; this forces bits higher than 0x80 (i.e., bits 0x100, 0x200, 0x400, ...) to zero but leaves the lower 8 bits as is.
You can also write these; they are all equivalent:
int pos = ((int) b) & 0xFF; // convert b to int first, then strip high bits
int pos = b & 0xFF; // done as int arithmetic -- the cast is not needed
Java automatically 'promotes' integer types whose size (in # of bits) is smaller than int to an int value when doing arithmetic. This is done to provide a more deterministic result (than say C, which is less constrained in its specification).
You may want to have a look at this question on casting a 'short'.