Casting long to byte in Java
Asked Answered
R

5

4

I am unable to understand the following:

In java,

long l = 130L;  
byte b = (byte)l;

If I print the value of b, why do I get -126? What is the bit representation of long l?

Reticulate answered 11/4, 2011 at 16:0 Comment(1)
I don't think that code even compilesFerrari
D
9

Bytes are signed in Java - so the range of values is -128 to 127 inclusive.

The bit pattern for 130 as a long, when simply truncated to 8 bits, is the bit pattern for -126 as a byte.

As another example:

int x = 255;
byte b = (byte) x; // b is now -1
Daybook answered 11/4, 2011 at 16:2 Comment(2)
Thank you Jon. But what is the bit value in l ? 130 in binary equal to '10000010' so how does the truncation occur here ? what is the value in l which gets truncated to become -126 .. ?Reticulate
@Pan: That's exactly the bit pattern... which in 2's complement (en.wikipedia.org/wiki/Two's_complement) for an 8-bit value is -126. Do you understand my example, where '11111111' ends up as -1? It's exactly the same principle.Daybook
I
15

A byte is a sequence of 8 bits, which makes 2^8 cases = 256. Half of them represent negative numbers, which is -128 to -1. Then there is the 0, and about the half, 1 to 127 represent the positive numbers.

130 as Int looks like 128 + 2 which is:

0000:0000 1000:0000 (128) 
0000:0000 0000:0010 (2) 
0000:0000 1000:0010 (130) 

However, the Byte has just 8 digits, and the assignment takes just the bits as they are, but just the last ones:

1000:0010 

The first bit indicates, it is a negative number. Now how much do you need to add to get to zero? Let's do it stepwise:

1000:0010 x + 
0000:0001 1 = 
----------------
1000:0011 (x+1) 

1000:0011 (x+1) +
0000:0001 1 = 
----------------
1000:0100 (x+2) 

Lets do bigger steps. Just add 1s where we have zeros, but first we go back to x:

1000:0010 x + 
0111:1101 y = 
--------------
1111:1111 

Now there is the turning point: we add another 1, and get zero (plus overflow)

1111:1111 (x + y) + 
0000:0001 1
--------- 
0000:0000 0

If (x+y) + 1 = 0, x+y = -1. A minus 1 is, interestingly, not just the same as 1 (0000:0001) with a 'negative-flag' set ('1000:0001'), but looks completely different. However, the first position always tells you the sign: 1 always indicates negative.

But what did we add before?

0111:1101 y = ?

It doesn't have a 1 at the first position, so it is a positive value. We know how to deconstruct that?

 ..f:8421 Position of value (1, 2, 4, 8, 16=f, 32, 64 in opposite direction)
0111:1101 y = ?
 ..f 84 1 = 1+4+8+16+32+64= 125

And now it's clear: x+125 = -1 => x = -126

You may imagine the values, organized in a circle, with the 0 at the top (high noon) and positive values arranged like on a clock from 0 to 5 (but to 127), and the turning point at the bottom (127 + 1 => -128 [sic!].) Now you can go on clockwise, adding 1 leads to -127, -126, -125, ... -3, -2, -1 (at 11 o'clock) and finally 0 at the top again.

For bigger numbers (small, int, long) take bigger clocks, with the zero always on top, the maximum and minimum always on bottom. But even a byte is much too big, to make a picture, so I made one of a nibble, a half-byte:

bitpatterns of integer, arranged in circle form

You can easily fill the holes in the picture, it's trivial!

Btw.: the whole thing isn't called casting. Casting is only used between Objects. If you have something, which is in real a subtype:

 Object o = new String ("casting or not?"); 

this is just an assignment, since a String is (always) an Object. No casting involved.

 String s = (String) o; 

This is a casting. To the more specific type. Not every object is a String. There is a small relationship to integer promotion, since every byte can be lossless transformed to long, but not every long to byte. However, even Byte and Long, the Object-types, aren't inherited from each other.

You just don't get a warning, for

byte s = (byte) 42;
long o = s; // no problem, no warning
byte b = (byte) o; // written like casting 
Inclinatory answered 11/4, 2011 at 16:20 Comment(1)
this should be the accepted answer, very informative. Thanks for the effort!Childbearing
D
9

Bytes are signed in Java - so the range of values is -128 to 127 inclusive.

The bit pattern for 130 as a long, when simply truncated to 8 bits, is the bit pattern for -126 as a byte.

As another example:

int x = 255;
byte b = (byte) x; // b is now -1
Daybook answered 11/4, 2011 at 16:2 Comment(2)
Thank you Jon. But what is the bit value in l ? 130 in binary equal to '10000010' so how does the truncation occur here ? what is the value in l which gets truncated to become -126 .. ?Reticulate
@Pan: That's exactly the bit pattern... which in 2's complement (en.wikipedia.org/wiki/Two's_complement) for an 8-bit value is -126. Do you understand my example, where '11111111' ends up as -1? It's exactly the same principle.Daybook
O
2

You mean byte b = (byte)l?

Java's types are signed, so bytes allow numbers between -128 and +127.

Oxidation answered 11/4, 2011 at 16:2 Comment(0)
H
1

For beginners to understand: 1 byte = 8 bits Range (derived from 2's complement no. system) = [-2^(n-1) to 2^(n-1)-1], where n is no. of bits So range is -128 to 127

Whenever value is incremented more than highest possible +ve value, the flow goes to the lowest possible -ve value.

So after value reaches 127 , flow continues from -128 to -127 to -126 to cover a total space of 130 and the thus o/p is -126

Humor answered 10/4, 2021 at 16:35 Comment(3)
I think you mean range of byte is -128 to 127. Range of int is -2147483648 to 2147483647.Flit
Yes ..I meant byteHumor
Your title is misleading and there is no question in your post.Vellavelleity
G
0

An unsigned byte holds values 0 to 255, so the number 130 can fit inside it, but when it's a signed byte, it can only go up to 127, so 130 isn't going to store properly.

Since the number is stored in Twos-complement format, you can subract 256 if the number is larger than 127. 130 is larger than 127 so 130 - 256 = -126.

Also keep in mind that any other bits past the first 8 will be lost. If you have a long valLong = 257, that is 9 bits, so when converting to a byte it loses some information and becomes a value of 1 (257 as a long is 00000000_00000000_00000000_00000000_00000000_00000000_00000001_00000001 but a byte can only hold the last part: 00000001.

Guan answered 2/4, 2023 at 3:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.