byte.parse() doesn't like 8 bit - java

This code
byte b = Byte.parseByte("10000000", 2);
throws an exception in Java. This should be -128 or 255.
Byte has 8 bit. Why can't I parse a 8 bit string?

The reason is down to the range of a byte in Java. Bytes are signed, so you can have anything from -128 ("-10000000") through to 127 ("1111111"), but no values outside that range.

The MAX_VALUE of a byte in java (or in C#) is 127 where as 10000000 return 128 which cannot be stored in a byte variable

What you can do treat the value as signed this way.
byte b = (byte) Integer.parseInt("10000000", 2);

Strictly, you passed not eight bits to parse method, but string representation of usual number with radix 2. And it may contain a sign character. Particularly, byte b = Byte.parseByte("-10000000", 2) works nice and gives -128.

That's not an 8-bit string, it's an 8-character string, and it's not being read the way you think it is...
From the MSDN documentation (here), you'll see that byte.Parse accepts strings in the integer format. So, you're trying to parse 10 million, not -1. The exception you're getting gives this away: you should see an OverflowException.
byte.parse("255") gives the effect you expect (byte is unsigned; using -128 also gives an overflow).

Related

unsigned bytes in Java byte array

This may seem like an easy question, but I'm so confused.
byte[] bArray = new byte[]{(byte) (0x80 & 0xff)};
System.out.println(bArray[0]);
and my output is -128. Why?
How can I rewrite this so that the byte array contains 128?
I thought that the 0xff made it unsigned.
Thanks for your help!
I thought that the 0xff made it unsigned.
Well, it does, sort of - it promotes it to an int, and keeps just the last 8 bits.
However, you're then casting the result of that back to a byte, and a byte in Java is always signed. (It's annoying, but it's the way it is.) So you might as well just have written:
byte[] bArray = { (byte) 0x80 };
The result would be exactly the same.
You're storing the bit pattern you want to store (10000000) so if you're transmitting this elsewhere, you don't need to worry... it's just when you're viewing it as a byte in Java that it's annoying.
Value range of byte according Java Language Specification 4.2.1
For byte, from -128 to 127, inclusive
so there is no way (in Java) that a byte will hold (byte) 128.
You can cast the byte to an int and apply & 0xff to get the unsigned representation of the byte (as an int). But if you cast it back to an byte it will again be interpreted as being a signed value between -128 and 127...
If you are only concerned with printing:
System.out.println(bArray[0] & 0xff);
or, for hexadecimal
System.out.printf("0x%02x\n", bArray[0]);
My answer is attached in the big picture

Why does Byte.parseByte("80", 16) fail?

System.out.println(Byte.toString( (byte)(1 << 7) ));//print "-128"
System.out.println(Byte.parseByte("80", 16));//run time exception java.lang.NumberFormatException: Value out of range. Value:"80" Radix:16
Why does the first succeed while the second fails? One might expect that they produce the same output.
Hexadecimal 0x80 is 128 in decimal. Bytes can only hold values from -128 to 127, inclusive. So, when you try to parse a value of 128, it fails because that value can't be represented as a byte.
If you want to parse a negative value, you need to include a negative sign:
System.out.println(Byte.parseByte("-80", 16)); /* Prints -128 */
When performing a narrowing conversion, for example, from int to byte as in this example, information about the overall magnitude of a value can be lost. Casting an int value to byte simply discards all but the lowest 8 bits, so casting int 128 to byte yields -128.
The first operator is a binary shift. -128 represents 0b10000000 in binary code. The 1 shifted seven times to the left.
In the second statement, the radix you're using is for hex numbers as you can see in Tutorialspoint's example. If you change your statement to System.out.println(Byte.parseByte("80", 10));, you won't get the exception.
Hope this explanations was of help.

How do I convert a Hex value (example: 0xD1) to a unsigned Byte in Java?

I am trying to take hex values and move them into a byte array. When I do this they are not converted how I need them to be. Most of them are converted to negative numbers. For example, after the execution of the C# code "baCommandPDI[0] = 0xD1;", the value of baCommandPDI[0] is "209". This is what I need. No matter what I try in Java, the value is "-47". I need it to be "209" in the byte array, because this byte array is sent out over TCP/IP to some external hardware. The external hardware cannot interpret -47 as 209. It must be 209. I have tried the following code:
int intTemp = 0xD1; After this line is executed the value of intTemp is 209, great!
int intHexValue = 0xD1 & 0xFF; After this line is executed the value of intHexValue is still 209, I don't understand how, but it ia what it is.
baCommand[0] = (byte) intHexValue; After this line is executed the value of baCommand[0] is -47, bad. This is not what I want. Everytime it converts the value to a byte it makes it signed.
Is there any other way I can do this? Can I use 11010001 and some how assign that value to a byte without making it negative?
In Java, bytes are always signed. But like an unsigned byte in another language, 8 bits are still used. The byte representations for 209 (unsigned) and -47 are the same.
1101 0001
The only difference is how Java interprets the most significant bit -- -128 vs. 128 in an unsigned type. The difference is 256, which is the difference between 209 and -47. You can send the value as is, because the bit values are the same, only the interpretations of this bit pattern are different.
If you would like to convert the value -47 to 209 to convince yourself in Java, you can promote the type to a longer primitive type and mask out the last 8 bits. This line will do this is one line, so you can debug and see that the bits are the same and that the unsigned version is equivalent.
int test = baCommandPDI[0] & 0xFF;
Printing/debugging test will let you see the value 209.
Java does not have a concept of unsigned bytes.
To get 209 from 0xD1, try:
0xD1 & 0xFF;

Store signed value in Byte

I was trying to store byte value in a variable and trying to perform some logic based upon this calculation.
byte mByteValue = -129; // Holding byte value
Problem is I am always getting value 127, due to which my logic fails everytime.
Any specific reason behind this, why its behaving strange in my case?
A byte in java is a signed 8-bit value. 8 bits gives you 256 possible values, but since a byte is signed and can represent positive and negative values, those 256 values must be roughly split in half across the possible positive and negative values. So you can't store negative values past -128; in particular don't expect to be able to store -256.
What you're actually observing when your byte has the value 127 is known as overflow (see this wiki article)
If you need to manipulate values outside this range, as in your example code, or e.g. an unsigned byte, at some point you'll need to make use of a wider integer type, like short.
The standard libraries provide these limits as Byte.MIN_VALUE and Byte.MAX_VALUE (docs here and here).
The range of byte is from -128 to 127. You can not store any value beyond these range.
This is because byte is 8 bits. So the maximum positive number stored at byte is -
2^7 -1 = 127. // since the first bit is sing bit; 0 for positive
And minimum negative number stored at byte is-
2^7 = -128 //since the first bit is sign bit; 1 for negative.
And if you use unsigned byte the it would be 255.
To correctly convert a byte to an int use mByteValue & 0xFF. You can read more about the Two's complement here: https://en.wikipedia.org/wiki/Two%27s_complement.

Is this statement correct in java?

I would like to do a data transfer between two computers using datagram socket.Iam using the following line this way :
host=InetAddress.getByAddress("mypc",new byte[]{192,168,1,110});
but when i use the above statement i get this error :"Possible loss of precision"
So i cast the int to bytes this way :
InetAddress.getByAddress("mypc",new byte[]{(byte)192,(byte)168,(byte)1,(byte)110});
Would the above statement work now ???
If you already have it in a string, just use getByName():
InetAddress host = InetAddress.getByName("192.168.1.110");
Using bytes is cluttered, and possibly dangerous (due to signed byts used in Java). Stick with Strings if you can.
There's no problem casting the positive integer literals into byte values, even if they overflow.
The InetAddress.getByAddress() function copes perfectly well with the fact that values exceeding 127 will be converted into negative numbers.
The only thing you need to watch out for is converting the signed bytes back into integers if you subsequently want to display them. This works fine:
byte b = (byte)192;
System.out.println(b); // outputs "-64"
int i = (b & 0xff);
System.out.println(i); // outputs "192"
java bytes are signed (stupid, I know) so larger than 127 is not possible.
See alnitaks' response for a more complete (and later:) answer.
It might not, cos the max value for a byte is 127 and beyond that it would rollover to the negative -64 for 192, -88 for 168 and so on...

Categories

Resources