Reputation: 7951
int i =132;
byte b =(byte)i; System.out.println(b);
Mindboggling. Why is the output -124
?
Upvotes: 131
Views: 296181
Reputation: 1
converting 'int' into 'byte' is like fitting big object into small box
if sign in -ve takes 2's complement
example 1: let number be 130
step 1:130 interms of bits =1000 0010
step 2:condider 1st 7 bits and 8th bit is sign(1=-ve and =+ve)
step 3:convert 1st 7 bits to 2's compliment
000 0010
-------------
111 1101
add 1
-------------
111 1110 =126
step 4:8th bit is "1" hence the sign is -ve
step 5:byte of 130=-126
Example2: let number be 500
step 1:500 interms of bits 0001 1111 0100
step 2:consider 1st 7 bits =111 0100
step 3: the remained bits are '11' gives -ve sign
step 4: take 2's compliment
111 0100
-------------
000 1011
add 1
-------------
000 1100 =12
step 5:byte of 500=-12
example 3: number=300
300=1 0010 1100
1st 7 bits =010 1100
remaining bit is '0' sign =+ve need not take 2's compliment for +ve sign
hence 010 1100 =44
byte(300) =44
Upvotes: 0
Reputation: 89623
132
in digits (base 10) is 1000_0100
in bits (base 2) and Java stores int
in 32 bits:
0000_0000_0000_0000_0000_0000_1000_0100
Algorithm for int-to-byte is left-truncate; Algorithm for System.out.println
is two's-complement (Two's-complement is if leftmost bit is 1
, interpret as negative one's-complement (invert bits) minus-one.); Thus System.out.println(int-to-byte(
))
is:
0000_0000_0000_0000_0000_0000_1000_0100
) [)))] )1000_0100
[)))] )1000_0100
))))1000_0011
)))0111_1100
))Upvotes: 91
Reputation: 9
If you want to understand this mathematically, like how this works
so basically numbers b/w -128 to 127 will be written same as their decimal value, above that its (your number - 256).
eg. 132, the answer will be 132 - 256 = - 124 i.e.
256 + your answer in the number 256 + (-124) is 132
Another Example
double a = 295.04;
int b = 300;
byte c = (byte) a;
byte d = (byte) b; System.out.println(c + " " + d);
the Output will be 39 44
(295 - 256) (300 - 256)
NOTE: it won't consider numbers after the decimal.
Upvotes: 1
Reputation: 4154
In Java, an int
is 32 bits. A byte
is 8 bits
.
Most primitive types in Java are signed, and byte
, short
, int
, and long
are encoded in two's complement. (The char
type is unsigned, and the concept of a sign is not applicable to boolean
.)
In this number scheme the most significant bit specifies the sign of the number. If more bits are needed, the most significant bit ("MSB") is simply copied to the new MSB.
So if you have byte 255
: 11111111
and you want to represent it as an int
(32 bits) you simply copy the 1 to the left 24 times.
Now, one way to read a negative two's complement number is to start with the least significant bit, move left until you find the first 1, then invert every bit afterwards. The resulting number is the positive version of that number
For example: 11111111
goes to 00000001
= -1
. This is what Java will display as the value.
What you probably want to do is know the unsigned value of the byte.
You can accomplish this with a bitmask that deletes everything but the least significant 8 bits. (0xff)
So:
byte signedByte = -1;
int unsignedByte = signedByte & (0xff);
System.out.println("Signed: " + signedByte + " Unsigned: " + unsignedByte);
Would print out: "Signed: -1 Unsigned: 255"
What's actually happening here?
We are using bitwise AND to mask all of the extraneous sign bits (the 1's to the left of the least significant 8 bits.) When an int is converted into a byte, Java chops-off the left-most 24 bits
1111111111111111111111111010101
&
0000000000000000000000001111111
=
0000000000000000000000001010101
Since the 32nd bit is now the sign bit instead of the 8th bit (and we set the sign bit to 0 which is positive), the original 8 bits from the byte are read by Java as a positive value.
Upvotes: 176
Reputation: 160
A quick algorithm that simulates the way that it work is the following:
public int toByte(int number) {
int tmp = number & 0xff
return (tmp & 0x80) == 0 ? tmp : tmp - 256;
}
How this work ? Look to daixtr answer. A implementation of exact algorithm discribed in his answer is the following:
public static int toByte(int number) {
int tmp = number & 0xff;
if ((tmp & 0x80) == 0x80) {
int bit = 1;
int mask = 0;
for(;;) {
mask |= bit;
if ((tmp & bit) == 0) {
bit <<=1;
continue;
}
int left = tmp & (~mask);
int right = tmp & mask;
left = ~left;
left &= (~mask);
tmp = left | right;
tmp = -(tmp & 0xff);
break;
}
}
return tmp;
}
Upvotes: 2
Reputation: 234695
Conceptually, repeated subtractions of 256 are made to your number, until it is in the range -128 to +127. So in your case, you start with 132, then end up with -124 in one step.
Computationally, this corresponds to extracting the 8 least significant bits from your original number. (And note that the most significant bit of these 8 becomes the sign bit.)
Note that in other languages this behaviour is not defined (e.g. C and C++).
Upvotes: 0
Reputation: 47078
In Java, byte
(N=8) and int
(N=32) are represented by the 2s-complement shown above.
From the equation, a7 is negative for byte
but positive for int
.
coef: a7 a6 a5 a4 a3 a2 a1 a0
Binary: 1 0 0 0 0 1 0 0
----------------------------------------------
int: 128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = 132
byte: -128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = -124
Upvotes: 4
Reputation: 1
N is input number
case 1: 0<=N<=127 answer=N;
case 2: 128<=N<=256 answer=N-256
case 3: N>256
temp1=N/256;
temp2=N-temp*256;
if temp2<=127 then answer=temp2;
else if temp2>=128 then answer=temp2-256;
case 4: negative number input
do same procedure.just change the sign of the solution
Upvotes: -1
Reputation: 4454
here is a very mechanical method without the distracting theories:
This more practical method is in accordance to the much theoretical answers above. So, those still reading those Java books saying to use modulo, this is definitely wrong since the 4 steps I outlined above is definitely not a modulo operation.
Upvotes: 6
Reputation: 37
often in books you will find the explanation of casting from int to byte as being performed by modulus division. this is not strictly correct as shown below what actually happens is the 24 most significant bits from the binary value of the int number are discarded leaving confusion if the remaining leftmost bit is set which designates the number as negative
public class castingsample{
public static void main(String args[]){
int i;
byte y;
i = 1024;
for(i = 1024; i > 0; i-- ){
y = (byte)i;
System.out.print(i + " mod 128 = " + i%128 + " also ");
System.out.println(i + " cast to byte " + " = " + y);
}
}
}
Upvotes: 2
Reputation: 533500
132 is outside the range of a byte which is -128 to 127 (Byte.MIN_VALUE to Byte.MAX_VALUE) Instead the top bit of the 8-bit value is treated as the signed which indicates it is negative in this case. So the number is 132 - 256 = -124.
Upvotes: 16
Reputation: 231133
byte in Java is signed, so it has a range -2^7 to 2^7-1 - ie, -128 to 127. Since 132 is above 127, you end up wrapping around to 132-256=-124. That is, essentially 256 (2^8) is added or subtracted until it falls into range.
For more information, you may want to read up on two's complement.
Upvotes: 23