Bitwise left shift behaviour - java

Today I was learning about the left shift bit operator (<<). As I understand it the left shift bit operator moves bits to the left as specified. And also I know multiply by 2 for shifting. But I am confused, like what exactly is the meaning of "shifting bits" and why does the output differ when value is assigned with a different type?
When I call the function below, it gives output as System.out.println("b="+b); //Output: 0
And my question is: how does b become 0 and why is b typecasted?
public void leftshiftDemo()
{
byte a=64,b;
int i;
i=a << 2;
b=(byte)(a<<2);
System.out.println("i="+i); //Output: 256 i.e 64*2^2
System.out.println("b="+b); //Output: 0 how & why b is typecasted
}
Update (new doubt):
what does it mean "If you shift a 1 bit into high-order position (Bit 31 or 63), the value will become negative". eg.
public void leftshifHighOrder()
{
int i;
int num=0xFFFFFFE;
for(i=0;i<4;i++)
{
num=num<<1;
System.out.println(num);
/*
* Output:
* 536870908
* 1073741816
* 2147483632
* -32 //how this is -ve?
*/
}
}

When integers are casted to bytes in Java, only the lowest order bits are kept:
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.
In this case the byte 64 has the following binary representation:
01000000
The shift operator promotes the value to int:
00000000000000000000000001000000
then left shifts it by 2 bits:
00000000000000000000000100000000
We then cast it back into a byte, so we discard all but the last 8 bits:
00000000
Thus the final byte value is 0. However, your integer keeps all the bits, so its final value is indeed 256.

In java, ints are signed. To represent that, the 2's complement is used. In this representation, any number that has its high-order bit set to 1 is negative (by definition).
Therefore, when you left-shift a 1 that is on the 31st bit (that is the one before last for an int), it becomes negative.

i = a << 2;
in memory:
load a (8 bits) into regitry R1 (32 bits)
shift registry R1 to the left two position
assign registry R1 (32 bits) to variable i (32 bits).
b = (byte)(a << 2);
in memory:
load a (8 bits) into regitry R1 (32 bits)
shift registry R1 to the left two position
assign registry R1 (32 bits) to variable b (8 bits). <- this is why cast (byte) is necessary and why they get only the last 8 bits of the shift operation

The exact meaning of shifting bits is exactly what it sounds like. :-) You shift them to the left.
0011 = 3
0011 << 1 = 0110
0110 = 6

You should read about different data types and their ranges in Java.
Let me explain in easy terms.
byte a=64,b;
int i;
i=a << 2;
b=(byte)(a<<2);
'byte' in Java is signed 2's complement integer. It can store values from -128 to 127 both inclusive. When you do this,
i = a << 2;
you are left shifting 'a' by 2 bits and the value is supposed to be 64*2*2 = 256. 'i' is of type 'int' and 'int' in Java can represent that value.
When you again left shift and typecast,
b=(byte)(a<<2);
you keep your lower 8 bits and hence the value is 0.
You can read this for different primitive types in Java.
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

Related

How does cast in java work? [duplicate]

int i =132;
byte b =(byte)i; System.out.println(b);
Mindboggling. Why is the output -124?
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.
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:
interpret-as( if-leftmost-bit-is-1[ negative(invert-bits(minus-one(] left-truncate(0000_0000_0000_0000_0000_0000_1000_0100) [)))] )
=interpret-as( if-leftmost-bit-is-1[ negative(invert-bits(minus-one(] 1000_0100 [)))] )
=interpret-as(negative(invert-bits(minus-one(1000_0100))))
=interpret-as(negative(invert-bits(1000_0011)))
=interpret-as(negative(0111_1100))
=interpret-as(negative(124))
=interpret-as(-124)
=-124 Tada!!!
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.
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.
here is a very mechanical method without the distracting theories:
Convert the number into binary representation (use a calculator ok?)
Only copy the rightmost 8 bits (LSB) and discard the rest.
From the result of step#2, if the leftmost bit is 0, then use a calculator to convert the number to decimal. This is your answer.
Else (if the leftmost bit is 1) your answer is negative. Leave all rightmost zeros and the first non-zero bit unchanged. And reversed the rest, that is, replace 1's by 0's and 0's by 1's. Then use a calculator to convert to decimal and append a negative sign to indicate the value is negative.
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.
Two's complement Equation:
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
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);
}
}
}
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;
}
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.
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++).
In java int takes 4 bytes=4x8=32 bits
byte = 8 bits range=-128 to 127
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
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

Java, combining two integers to long results negative number

I am trying to combining two integers to a long in Java. Here is the code I am using:
Long combinedValue = (long) a << 32 | b;
When a = 0x03 and b = 0x1B56 ED23, I am able to get the expected value (combinedValue = 13343583523 in long).
However, when my a = 0x00 and b = 0xA2BF E1C7, I get a negative value, -1567628857, instead of 2730484167. Can anyone explain why shifting an integer 0 by 32 bits causes the first 32 bits become 0xFFFF FFFF?
Thanks
b is negative, too. That's what that constant means. What you probably want is ((long) a << 32) | (b & 0xFFFFFFFFL).
When you OR (long) a << 32 with b, if b is an int then it will be promoted to a long because the operation must be done between two values of the same type. This is called a widening conversion.
When this conversion from int to long happens, b will be sign extended, meaning that if the top bit is set then it will be copied into the top 32 bits of the 64 bit long value. This is what causes the top 32 bits to be 0xffffffff.

Converting integer variable to byte variable

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

Restricting Binary Output to 8 bits or 4 bits

Here is my FIRST Question
Here is my code:
public class Bits{
public static void main(String args[]){
int i = 2 , j = 4;
int allOnes = ~0;
int left = allOnes << (j+1);
System.out.println("Binary Equivalent at this stage: " +Integer.toBinaryString(left));
}
}
The following is the output I'm getting:
Binary Equivalent at this stage: 11111111111111111111111111100000
How can I restrict it to only 8 bits from the right hand side. I mean 11100000 .
Please explain.
Here is my SECOND Question:
Also, I have one more Question which is totally different with the above one:
public static void main(String args[]){
int i = 2 , j = 4;
int allOnes = ~0; // will equal sequence of all 1s
int left = allOnes << (j+1);
System.out.println("Binary Equivalent at this stage: " +Integer.toBinaryString(left));
}
}
Since I didn't understand the following line:
int allOnes = ~0; // will equal sequence of all 1s
When I tried to output the value of "allOnes" then I got "-1" as my output.
I'm having hard time understanding the very next line which is as follows:
int left = allOnes << (j+1);
int allOnes = ~0;
Takes the integer 0 and applies the NOT operation bitwise so it will have all ones in its binary representation. Intagers use the two's complement format, meaning that a value of a word having all bits as one is value of -1.
If you only care about byte boundaries, then use a ByteBuffer
byte lastByte = ByteBuffer.allocate(4).putInt(i).array()[3];
To restrict this byte to the first four or last four bits, use lastByte & 0b11110000 or lastByte & 0b00001111
The integer representation of -1 is all 1's, i.e. 32 bits all set to 1. You can think of the first bit as -2^31 (note the negative sign), and of each subsequent bit as 2^30, 2^29, etc. Adding 2^0 + 2^1 + 2^2 ... + 2^30 - 2^31 = -1.
I suggest reading this tutorial on bitwise operations.
For #1 Integer.toBinaryString(left) is printing 32 bits (length of Integer), so if you just want the right 8 you can do the following:
Integer.toBinaryString(left).substring(24)
The ~ operator in Java inverts the the bit pattern. Thus 0 turns into ffff.
The << operator shifts the bits by x. You are shifting the bits to the left by 5 so you end up with 5 zeros on the right.
Here are all the bitwise operators for Java
First, a more general solution for the first question than what I've seen so far is
left &= (2 ^ n) - 1;
where n is the number of binary digits that you want to take from the right. This is based around the bitwise AND operator, &, which compares corresponding bits in two numbers and outputs a 1 if they are both 1s and 0 otherwise. For example:
10011001 & 11110000 == 10010000; // true
This is used to create what are known as bitmasks (http://en.wikipedia.org/wiki/Mask_(computing)). Notice how in this example how the left 4 bits of the first number are copied over to the result and how those same 4 bits are all ones in the second number? That's the idea in a bit mask.
So in your case, let's look at n = 8
left &= (2 ^ 8) - 1;
left &= 256 - 1;
left &= 255; // Note that &=, like += or *=, just means left = left & 255
// Also, 255 is 11111111 in binary so it can be used as the bitmask for
// the 8 rightmost bits.
Integer.toBinaryString(left) = "11100000";
Your second question is much more in depth, but you'd probably benefit most from reading the Wikipedia article (http://en.wikipedia.org/wiki/Two's_complement) instead of trying to understand a brief explanation here.
8 bits in decimal has a maximum value of 255. You can use the modulo (remainder) division operator to limit it to 8 bits at this point. For isntance:
int yournum = 35928304284 % 256;
will limit yournum to 8 bits of length. Additionally, as suggested in the comments, you can do this:
int yournum = 3598249230 & 255;
This works as well, and is actually preferred in this case, because it is much faster. The bitwise and function returns 1 if both associated bits are 1; since only the last 8 bits of 255 are one, the integer is implicitly limited to 255.
To answer your second question: A tilde is the bitwise inversion operator. Thus,
int allOnes = ~0;
creates an integer of all 1s. Because of the way twos complements works, that number actually represents -1.

How are integers cast to bytes in Java?

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'.

Categories

Resources