Byte initialization using 0xFF instead of 0xFFFFFFFF - java

I have a question about initializing byte in java, I want to initialize a byte value allBitsOne and all bits of it are 1:
Method 1:
byte allBitsOne = 0xFF;
Wrong, it says that 0xFF is a integer type and over the range of byte, so i do it like below
Method 2:
byte allBitsOne = (byte)0xFF;
Works fine.
Method 3:
byte allBitsOne = 0xFFFFFFFF;
It works fine as well, but if 0xFF exceeds the range of a byte, why doesn't 0xFFFFFFFF?
Thank you all, I found this: link

byte is a signed integer type, going from -128 to 127.
0xFF is 255, so it's larger than 127.
0xFFFFFFFF is -1, so it's within the bounds of the byte type.
See http://en.wikipedia.org/wiki/Two%27s_complement

literal integers in Java are signed 32 bit numbers, so:
0xff is an integer type which equals to 255, which is over the limit for byte.
0xffffffff is an integer type which equals to -1, which is not over the limit for byte.

the byte-variable in the java in the java can hold the values from -128 to 127.
if you want to set all the bit to 1. then u can store the -128 to it.

Related

Can Java's byte actually store 32bit?

My goal is to understand how byte is stored in Java.
System.out.println("(byte) 0xFF:\r\n" +
Integer.toBinaryString((byte) 0xFF));
My expected result of (byte) 0xFF is 0xFF.
My actual result of (byte) 0xFF is 0xFFFFFFFF
The output:
(byte) 0xFF:
11111111111111111111111111111111
If this is true, does storing negative number in byte actually is no different than storing negative number in int?
toBinaryString accepts an int. Your input was just autopromoted to int, hence it was represented with 32 digits (0xFF == -1 in two's complement, which promoted to int becomes 0xFFFFFFFF which is still -1 but represented with 32 bits, still in two's complement).
Notice that
If the unsigned magnitude is zero, it is represented by a single zero character '0' ('\u0030'); otherwise, the first character of the representation of the unsigned magnitude will not be the zero character.
Which means that if there are leading 0s they won't be part of the output (unless the output is 0), which means you'll get less than 32 digits.
When the byte is implicitly re-cast as an integer, it sees the first bit as a sign bit and when it stretches out to be 4 bytes long, it retains it's value as negative. You've effectively overflowed to the smallest negative integer value.
Java bytes are signed and can represent the values -128 to 127, and a hex value of 0xff is treated as -1. When you call Integer.toBinaryString, the byte is cast to an int, preserving the sign. The way this works is called sign extension, and the highest bit from the byte is copied all the way up. This is why you see 0xfffff...
To perform an unsigned conversion, mask the value with 0xff, which itself an int unless specified otherwise.
byte b = (byte) 0xff;
Integer.toBinaryString(b & 0xff);
And to answer your original question, Java doesn't really support a byte type as you might expect. It's always a 32-bit value except when dealing with byte arrays and byte buffers. Using a type of byte simply informs the JVM to perform certain type casting rules which have the effect of clearing or setting the upper bits accordingly.

java - Why is 0x000F stored as unsigned?

I was reading through examples trying to understand how to convert signed bytes to unsigned integer counter parts.
The most popular method that I have come across is:
a & 0xFF
Where a is the signed byte.
My question is why is 0xFF stored as unsigned? Are all hex values stored as unsigned? If so why?
And how does "and"-ing turn off the sign bit in the sign integer?
It would be great if someone could break down the process step by step.
You probably saw this in code that converted a byte to an integer, where they wanted to treat the byte as an unsigned value in the range 0-255. It does not apply to integers in general. If you want to make an integer a "unsigned", you can do:
int unsignedA = a & 0x7FFFFFFF;
This will ensure that unsignedA is positive - but it does that by chopping off the high bit, so for example if a was -1, then unsignedA is Integer.MAX_VALUE.
There is no way to turn a 32-bit signed Java integer into a 32-bit unsigned Java integer because there is no datatype in Java for a 32-bit unsigned integer. The only unsigned integral datatype in Java is 16 bits long: char.
If you want to store a 32-bit unsigned integral value in Java, you need to store it in a long:
long unsignedA = a & 0xFFFFFFFFL;
To elaborate on Erwin's answer about converting a byte to an integer: In Java, byte is a signed integer type. That means it has values in the range -128 to 127. If you say:
byte a;
int b;
a = -64;
b = a;
The language will preserve the value; that is, it will set b to -64.
But if you really want to convert your byte to a value from 0 to 255 (which I guess you call the "unsigned counterpart" of the byte value), you can use a & 0xFF. Here's what happens:
Java does not do arithmetic directly on byte or short types. So when it sees a & 0xFF, it converts both sides to an int. The hex value of a, which is a byte, looks like
a = C0
When it's converted to a 32-bit integer, the value (-64) has to be preserved, so that means the 32-bit integer has to have 1 bits in the upper 24 bits. Thus:
a = C0
(int)a = FFFFFFC0
But then you "and" it with 0xFF:
a = C0
(int)a = FFFFFFC0
& 000000FF
--------
a & FF = 000000C0
And the result is an integer in the range 0 to 255.
In Java, literals (1, 0x2A, etc) are positive unless you explicitly indicate that they are negative. It's how we intuitively write numbers.
This previous question answers you question about converting to unsigned. Understanding Java unsigned numbers

Converting 0xFF gives me -1 -> Signed vs Unsigned?

Here is my code:
byte b = (byte) 0xFF;
System.out.println(b);
I expect to see 255, but instead I see -1. What's happening? Is the compiler using a signed instead of an unsigned byte?
Maybe you are confused about the difference between storage and representation.
As the others told you, Java only uses signed integral types. As a byte is only 8 bit, this means you have a range from -128 to 127. But keep in mind: This is only a decimal representation that does not tell you about the binary storage!
A better reminder for the range of Java's byte type would be the following (decimal) representation:
0 1 ... 126 127 -128 -127 ... -2 -1
This directly corresponds to the following binary representation:
00000000 00000001 ... 11111110 11111111
The signed decimal representation is called the two's complement. As you can see, the binary value 11111111, which is exactly 0xFF, corresponds to the (signed) decimal value -1.
If you now send this value via a stream, you will get the full 0xFF value, regardless what you see in a Java program's console output.
In Java type byte is signed, it is not possible to use an "unsigned byte" in java. A workaround would be to use short types
Everytime you operate on a byte variable in Java, (byte) 0xFF is going to be implicitly converted to (int) 0xFFFFFF (i.e. -1). You can do 0xFFFFFF & 0xFF and then you'll get (int) 255 as you wish (you will never be able to get (byte) 255, only (int) 255).
If you only need to store bytes, it doesn't matter how 0xFF is printed on the screen, it's still (byte) 0xFF internally. If you need to operate on them (comparing to an int, adding, subtracting, converting to a string, printing on the screen, and basically anything else), then you need to be aware that they'll get converted to int 0xFFFFFF which is interpreted -1.

JAVA: why binary literal for byte with negative sign is being considered as integer type?

I can't understand the following behavior.
I'm trying to declare byte mask using binary literal:
byte mask = 0b1111_1111;
But that's not possible, because I get the following error message:
Type mismatch: cannot convert from int to byte
The most interesting thing is that when I try to declare the mask directly, in decimal representation
byte mask = -1;
I get no error, but these two representations should be absolutely equal!
What am I doing wrong?
Thanks in advance.
You can safely assign a values from -2^7 to 2^7-1 (-128 to 127) to a byte ,since it is 8 bits.
where as 0b1111_1111 = 255
So need a cast there
byte mask = (byte) 0b1111_1111;
The value 0b1111_1111 is equal to 255, outside the byte's range of [-128, 127](because it is signed). Use:
byte mask=(byte)0b1111_1111&0xff;
The narrowing will remove the (all-zero) high bits and fit 8 into 8 without regard for sign.
Your "byte mask" is equivalent to 0xff or 255, which are too large to fit in an 8-bit signed byte, not -1, because the literal in the code is an int. If the value is within the range of a smaller type, the compiler can safely stuff it in there, but it can't safely assign a value outside the range -128..127 to a byte variable, and you'll need a cast.
All numerical literals are considered as 'int', unless cast otherwise or they contain a decimal point or an 'e'.
you can do type casting like this
byte mask = (byte) 0b1111_1111;

Java how to parse uint8 in java?

I have a uint8 (unsigned 8 bit integer) coming in from a UDP packet. Java only uses signed primitives. How do I parse this data structure correctly with java?
Simply read it as as a byte and then convert to an int.
byte in = udppacket.getByte(0); // whatever goes here
int uint8 = in & 0xFF;
The bitmask is needed, because otherwise, values with bit 8 set to 1 will be converted to a negative int. Example:
This: 10000000
Will result in: 11111111111111111111111110000000
So when you afterwards apply the bitmask 0xFF to it, the leading 1's are getting cancelled out. For your information: 0xFF == 0b11111111
0xFF & number will treat the number as unsigned byte. But the resultant type is int
You can store 8-bit in a byte If you really need to converted it to an unsigned value (and often you don't) you can use a mask
byte b = ...
int u = b & 0xFF; // unsigned 0 .. 255 value
You can do something like this:
int value = eightBits & 0xff;
The & operator (like all integer operators in Java) up-casts eightBits to an int (by sign-extending the sign bit). Since this would turn values greater than 0x7f into negative int values, you need to then mask off all but the lowest 8 bits.
You could simply parse it into a short or an int, which have enough range to hold all the values of an unsigned byte.

Categories