Please explain how come the output is 9? - java

The output is 9 and I can't get my head around the whole bitwise XOR concept.
public class XOR {
public static void main( String[] args ) {
int a = 12;
int b = 5;
int c = a ^ b;
System.out.print( c );
}
}

XOR stands for exclusive or
Exclusive or or exclusive disjunction is a logical operation that outputs true only when inputs differ (one is true, the other is false)
in your case, it's a bitwise comparison, so each 0 and 1 at the same position is compared
first step is to translate values from decimal to binary
12 = 00001100
05 = 00000101
Then, you apply XOR
12 = 00001100
05 = 00000101
XOR = 00001001
Finally, you convert from binary to decimal
00001001 = 9

the XOR operator first converts both of your values into their binary equivalents. Binary operations will apply to corresponding bits, and the XOR operator evaluates to true (1) whenever the corresponding bits are not equal. For example, 2^1 = 3 [10 ^ 01] notice the first bits and the second bits are different, so both bits evaluate to 1.
In your example: 12 ^ 5
12 = 1 1 0 0
5 = 0 1 0 1
The first and the 4th bits are of opposite value, so the first and the fourth bits evaluate to 1, while the remaining bits evaluate to 0, so the solution is 1001 = 9

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 "int i = byte1 | 0x0200" vs "int i = byte1"?

In the page Wikipedia - Shifts in Java:
In bit and shift operations, the type byte is implicitly converted to
int. If the byte value is negative, the highest bit is one, then ones
are used to fill up the extra bytes in the int. So
byte b1=-5; int i = b1 | 0x0200;
will give i == -5 as result.
I understand that 0x0200 is equal to 0b0000 0010 0000 0000. But what is the significance of 0x0200 in the passage shown above?
I mean—b1 | 0x0200 will always be equal to i (see "My Test" below), then in the passage above, why not simply write byte b1=-5; int i = b1?
My Test:
public static void main(final String args[]) {
final byte min_byte = Byte.MIN_VALUE; // -128
final byte limit = 0; // according to the bolded words in the passage
for (byte b = min_byte; b < limit; ++b) {
final int i1 = b;
final int i2 = b | 0x0200;
if (i1 != i2) { // this never happens!
System.out.println(b);
}
}
}
But what is the significance of 0x0200 in the passage shown above?
This is done for illustration purposes only: the value 0x200 ORs in a one in a position that is equal to 1 already. The idea is to show that the result is not 0x000002FB, but actually -5, i.e. 0xFFFFFFFB.
I understand that 0x0200 is equal to 0b1111 1110 0000 0000
No, it isn't. The correct value is given by,
int i = 0x0200; // <-- decimal 512
System.out.println(Integer.toBinaryString(i));
Which outputs
1000000000
If we examine your second value,
byte b1 = -5;
System.out.println(Integer.toBinaryString(b1));
We get
11111111111111111111111111111011
Lining up both numbers
11111111111111111111111111111011
00000000000000000000001000000000
It seems clear that the result will be the bit value of -5 (since the only 0 in -5 is also 0 in 0x0200). To determine the significance we can examine
int i = 0x0200; // <-- Decimal 512
System.out.println("Dec: " + Integer.toBinaryString(i).length());
Output
Dec: 10
So, the given bitwise OR will force the tenth bit to be true. It was true in your input byte, but if you used - Decimal 1535 (0b 101 1111 1111) then you would get,
System.out.println(1535 | 0x0200);
Output is
2047
Because if you perform a bitwise-or on the two numbers
01000000000
10111111111
you get
11111111111

Difference between bitwise inclusive or and exclusive or in java

public class Operators {
public static void main(String[] args) {
int a = 12;
System.out.println("Bitwise AND:"+(12&12));
System.out.println("Bitwise inclusive OR:"+(12|12));
System.out.println("Bitwise exclusive OR:"+(12^12));
}
}
OUTPUT:
Bitwise AND:12
Bitwise inclusive OR:12
Bitwise exclusive OR:0
I understand first two, but not the third.
XOR tells whether each bit is different.
1 XOR 1 = 0
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 0 = 0
In other words "either but not both"
0011 XOR 0101 = 0110
BITWISE INCLUSIVE OR (|) means normal or operation ,
BITWISEE ExCLUSIVE OR (^) means xor operation
Third one is an XOR operation (Xclusive-OR)
It says, OR should be exclusively:
where similar will be False(0)
and dissimilar will be True(1).
So 12 in binary would be 1100
So, perform bitwise XOR here:
1 1 0 0
1 1 0 0
---------
0 0 0 0
---------
Every column has same digit, either both are 1's or both are 0's
XOR says, both should be different. Hence all zeros
Exclusive or (XOR) is defined as:
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0
That is, it is 0 when two values are the same, 1 if they are different.
So, given two bit patterns which are exactly equal, each XORed bit will evaluate to 0, as each bit will either have 1 in both positions, or 0 in both positions.

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 do I add binary numbers and ignore the carry?

Supposing the inputs are two integer values. I want to convert the two integer values to binary, perform binary addition, and give the result with the carry ignored (the integer equivalent). How would I go about doing this.
An idea that comes to mind is to convert them to binary strings in some way and use an algorithm for binary addition, and then ignore the carry (delete the carry character from the string, if the carry exists).
Sample Input
One number : 1
Second number : 3
Sample Output
2
Explanation:
The lowest bit in the sum is 1 + 1 = 0
The next bit is 0 + 1 = 1 (the carry from the previous bit is discarded)
The answer is 10 in binary, which is 2.
You are probably looking for the bitwise XOR (exclusive OR) which will provide the following outputs for the given inputs:
^ | 0 | 1
--+---+--
0 | 0 | 1
--+---+--
1 | 1 | 0
It behaves like binary addition ( 1+1 = 10) but ignores the overflow if both operands are 1.
int a = 5; // 101
int b = 6; // 110
a ^ b; // 3 or 011
This is just an XOR of the two integers in binary. In Java you can do
result = v1 ^ v2;

Categories

Resources