Can someone please explain this bitwise program to me? - java

public class UpCase {
public static void main(String[] args) {
int t;
byte val;
val = 123;
for (t = 128; t > 0; t = t / 2) {
System.out.println(t);
if ((val & t) != 0) System.out.println(" 1");
else System.out.println(" 0");
}
}
}
In particular, I am not sure why we are using val=123? I understand that this program will print out 123 in binary but why is that the case? How does this work? I do understand however, the principles of the & operator and how you can turn on and off bits but I am not sure how it works in this particular example?

This program will print out the binary digits of the number in val from MSB to LSB by comparing it to each power of 2:
123 : 01111011 &
128 : 10000000 =
00000000
00000000 != 0 => false, print 0
123 : 01111011 &
64 : 01000000 =
01000000
01000000 != 0 => true, print 1
123 : 01111011 &
32 : 00100000 =
00100000
00100000 != 0 => true, print 1
// repeat for 2^4-2^1...
123 : 01111011 &
1 : 00000001 =
00000001
00000001 != 0 => true, print 1

Very simple:
It just checks if the value (123 in this case) using the bitwise operator &. The result of that is 1 or 0, this process is repeated for the following value 0.5t etc until t=0, resulting in the binary string for this value 123.

Related

Understanding logic behind Integer.highestOneBit() method implementation

Java Integer class has the static method highestOneBit method which will return a value with a single one-bit, in the position of the highest-order one-bit in the specified value, or zero if the specified value is itself equal to zero.
For example input of int 17 will return 16; As 17 can be represented in binary as 10001 so it will return the furthest bit left which is equal to 16.
And in Integer class it has the following implementation in Java doc.
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
I just want to know the logic behind implementing it this way and the logic behind using shift operations
. Can any one put some light on it.
This algorithm calculates for a given i whose binary representation is:
0..01XXXXXXX...XXXX
the value
0..011111111...1111
That's what the 5 |= operators do.
Then, in the return statement, it subtracts from it that value shifted right by one bit
0..001111111...1111
to get the result
0..010000000...0000
How does it work:
The highest possible 1 bit the the 32nd (left most) bit. Suppose the input number has 1 in that bit:
1XXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
You or that value with the value shifted right by 1 (i >> 1) and get
11XXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
Then you or that new value with the value shifted right by 2 (i >> 2) and get
1111XXXX XXXXXXXX XXXXXXXX XXXXXXXX
Then you or that new value with the value shifted right by 4 (i >> 4) and get
11111111 XXXXXXXX XXXXXXXX XXXXXXXX
Then you or that new value with the value shifted right by 8 (i >> 8) and get
11111111 11111111 XXXXXXXX XXXXXXXX
Finally you or that new value with the value shifted right by 16 (i >> 16) and get
11111111 11111111 11111111 11111111
If the highest 1 bit is smaller than the 32nd bit, these operations still turn all the bits to the right of it to 1 and keep the remaining (higher bits) 0.
The i |= statements help to compute a sequence of ones that is the same length as i. For example, for 101011 it computes 111111. I've explained how it works in this answer (I can't retype it right now since I am on mobile).
So basically, once you have the string of ones, subtracting itself shifted right one bit gives the H.O. bit.
111111 - (111111 >>> 1) = 111111 - 011111 = 100000
The first five lines (i |= (i >> x)) will set every bit below the highest 1-bit to 1. Then, the final line will subtract every 1-bit below the highest one, so that only the highest 1-bit will remain.
For simplicity, let's pretend an int was 8 bits. The code would in that case be like this:
public static int highestOneBit(int i) {
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
return i - (i >>> 1);
}
Now, let's say we have the value 128 (10000000). This is what would happen:
// i == 10000000
i |= (i >> 1); // i = 10000000 | 11000000 = 11000000
i |= (i >> 2); // i = 11000000 | 11110000 = 11110000
i |= (i >> 4); // i = 11110000 | 11111111 = 11111111
return i - (i >>> 1); // 11111111 - 01111111 = 10000000
The >> is an arithmetic right shift, so it will preserve the signed bit.
The last >>> is a logical right shift, which will not preserve the signed bit. It will always insert zeroes on the left side.
Now, let's try with 64 (01000000):
// i == 01000000
i |= (i >> 1); // i = 01000000 | 00100000 = 01100000
i |= (i >> 2); // i = 01100000 | 00011000 = 01111000
i |= (i >> 4); // i = 01111000 | 00000111 = 01111111
return i - (i >>> 1); // 01111111 - 00111111 = 01000000

Right Shift Operator functionality in Java [duplicate]

This question already has answers here:
Difference between >>> and >>
(9 answers)
Closed 5 years ago.
int z = -1; int m = z>>1; System.out.println("the values is " +m);
Output is
the values is -1
but my doubt is how it happening internally, Can any explain? Step by step procedure.
int z = 2; int m = z>>1;
the z value in binary
00000000 00000000 00000000 00000010 ,
After the value is shifted then the m value in binary will be as
00000000 00000000 00000000 00000001 , when I print m value it will be as 1, but my question is, what is happening if I use negative value for z variable and when I assign z value with -1 why output variable has -1 itself? ( Two complement will happen are not?)
As described in JLS Sec 15.19:
The value of n >> s is n right-shifted s bit positions with sign-extension. The resulting value is floor(n / 2^s).
So, you are calculating -1 >> 1 == floor(-1 / 2) == floor(-0.5) = -1.

The Value of variable is going to negative value when performing some operation along with left Shift Operator in Java

public class Sample {
public static void main(String[] args) {
byte[] _temp1 = new byte[4];
byte[] _temp2 = new byte[4];
for(int i=0;i<_temp1.length; i++){
_temp1[i/8] |= (1<<(7-(i%8)));
System.out.println("Binary representation of _temp1["+(i/8)+"] is "+ Integer.toBinaryString(_temp1[i/8])+"decimal representation of temp1 is "+_temp1[i/8]);
_temp2[i/8] |=(1<<(i%8));
System.out.println("Binary representation of _temp2["+(i/8)+"] is "+ Integer.toBinaryString(_temp2[i/8])+"decimal representation of temp2 is "+_temp2[i/8]);
}
}
}
This is the code i am just using for reading a byte code from left to right i.e values are like 1,2,4,8,16,32,64,128 (_temp1[i/8] |= (1<<(7-(i%8)));)
and from right to left that's general way of representation of binary code i.e,
values are like 128,64,32,16,8,4,2,1 (_temp2[i/8] |= (1<<((i%8)));)
but, when I executed the above code the value that i am getting very different for first type the values are going to negatives when i converted them to decimals but next representation is showing normally .
Output:
Binary representation of _temp1[0] is 11111111111111111111111110000000decimal representation of temp1 is -128
Binary representation of _temp2[0] is 1decimal representation of temp2 is 1
Binary representation of _temp1[0] is 11111111111111111111111111000000decimal representation of temp1 is -64
Binary representation of _temp2[0] is 11decimal representation of temp2 is 3
Binary representation of _temp1[0] is 11111111111111111111111111100000decimal representation of temp1 is -32
Binary representation of _temp2[0] is 111decimal representation of temp2 is 7
Binary representation of _temp1[0] is 11111111111111111111111111110000decimal representation of temp1 is -16
Binary representation of _temp2[0] is 1111decimal representation of temp2 is 15
please explain why it is showing differently..Thanks for your time and valuable comments
1 in binary is 00000001. So 1 << 7 is 10000000 ( = - 128)
_temp1[i/8] |= (1<<(7-(i%8)));
case i = 0: 0/8 = 0
=> _temp1[0] |= 1 << 7
<=> _temp1[0] = _temp1[0] | 10000000
_temp1[0] default = 0 => _temp1[0] = 00000000 | 10000000 ( = 10000000)
case i = 1: 1/8 = 0 => _temp1[0] |= 1 << 6
<=> _temp1[0] = 10000000 | 01000000 ( = 11000000 <=> -64 in decimal )
case i = 2: 2/8 = 0 => _temp[0] |= 1 << 5
<=> _temp[0] = 11000000 | 00100000 ( = 11100000 <=> -32 in decimal)
Solution: change _temp1[i/8] to _temp1[i % 8]
and because max value of byte is 127, so if u wanna print 128:
change
byte[] _temp1 = new byte[4]
to
int[] _temp1 = new int[4]

How to increment bits correctly in an array?

If I have a binary notation such as "1000010" which equals 66 and I want to increment it by one to "1000011" which equals 67. How is that done correctly in my array? Currently it's printing out "0100010" which is 34, but no where near the correct answer. I don't think my array is shifting correctly, nor will it increase size as the numbers get larger. Although, I can't make any assumptions about how big the array can be other than what's explicitly stated.
public class math {
//=================================================================
// increment(A) returns an array of bits representing A+1.
//=================================================================
public static byte[] increment(byte[] A)
{
byte carry= 1;
for(int i = 0; i<A.length; i++){
byte b = A[i];
A [i] ^= carry;
carry &= b;
}
return A;
}
private static String toBinString (byte [] a)
{
String res = "";
for (int i = 0; i <a. length; i++)
{
res = (a [i] == 0 ? "0": "1") + res;
}
return res;
}
/**
* #param args
*/
public static void main(String[] args) {
byte [] A ={1,0,0,0,0,1,0};
increment(A);
System.out.println (toBinString (A));
}
}
The lazy (and secure) way for increment by one :
String s = "1000010";
for (int i = 0; i < 5; i++) {
System.out.print(s);
System.out.println("\t" + Integer.valueOf(s, 2));
s = Integer.toBinaryString(Integer.valueOf(s, 2) + 1);
}
Output :
1000010 66
1000011 67
1000100 68
1000101 69
1000110 70
(Edited for presentation)
This worked for me:
public static void main(String[] args) {
byte [] A ={1,0,0,0,0,1,0};
increment(A);
System.out.println (toBinString (A));
}
public static byte[] increment(byte[] A) {
boolean carry = true;
for (int i = (A.length - 1); i >= 0; i--) {
if (carry) {
if (A[i] == 0) {
A[i] = 1;
carry = false;
}
else {
A[i] = 0;
carry = true;
}
}
}
return A;
}
private static String toBinString (byte [] a) {
String res = "";
for (int i = 0; i < a. length; i++) {
res += (a [i] == 0 ? "0": "1") ;
}
return res;
}
//Function call
incrementCtr(ctr, ctr.length - 1);
//Increments the last byte of the array
private static void incrementCtr(byte[] ctr, int index) {
ctr[index]++;
//If byte = 0, it means I have a carry so I'll call
//function again with previous index
if(ctr[index] == 0) {
if(index != 0)
incrementCtr(ctr, index - 1);
else
return;
}
}
Late but concise:
public static void increment(byte[] a) {
for (int i = a.length - 1; i >= 0; --i) {
if (++a[i] != 0) {
return a;
}
}
throw new IllegalStateException("Counter overflow");
}
public static byte[] increment(byte[] array) {
byte[] r = array.clone();
for ( int i = array.length - 1; i >= 0; i-- ) {
byte x = array[ i ];
if ( x == -1 )
continue;
r[ i ] = (byte) (x + 1);
Arrays.fill( r, i + 1, array.length, (byte) 0 );
return r;
}
throw new IllegalArgumentException( Arrays.toString( array ) );
}
exception if overflow
In this case you can iterate on all values.
public boolean increment() {
int i = this.byteArray.length;
while (i-->0 && ++this.byteArray[i]==0);
return i != -1;
}
At the end you can increase the array's size.
There are many solutions on this page that represent a native Java byte as a full array of numeric one and zero values. In other words, a single single byte (with 8 bits) is represented as an entire array of 8 individual numeric values (where each index in the array is a byte itself that represents the 1 or 0 value of each bit position).
That means for a given input byte (8 bits), an 8 byte array (64 bits) is used to represent ones and zeros. Consequently, an input byte array of length 4 (e.g. representing an int or unsigned int), would require 32 bytes (256 bits), and an input byte array of length 8 (e.g. for a long) would require 64 bytes (512 bits), and so on.
Thats exponential (O(nc)) complexity - a relatively massive memory/performance expense to do something that the language already supports natively and efficiently. And if there are more than one of these byte array values to work with, that compounds the performance hit further.
The following is a correct (and working) solution if you have a standard byte array representing a single contiguous big-endian bit string and you want to increment it by one bit. It is nearly identical to Cristof R's solution, except that particular solution does not compile.
The following solution is most efficient if you don't need to create a copy of the input byte array, and is useful as an equivalent for iterator incrementation, e.g. i = i + 1 scenarios:
/**
* Treats the specified byte array as a single contiguous big-endian
* bit string, and increments it by a single bit. Does not throw an
* exception on overflow and instead 'rolls' over to zero.
*/
public static void increment(byte[] a) {
for (int i = a.length - 1; i >= 0; --i) {
if (++a[i] != 0) {
break;
}
}
}
If you don't want to modify the source bit string, you can just clone it before incrementing:
byte[] original = new byte[]{0, 0, 0, 0}; //integer value 0
byte[] copy = original.clone();
increment(copy);
Here's a little test program demonstrating:
public class IncrementBitExample {
/**
* Treats the specified byte array as a single contiguous big-endian
* bit string, and increments it by a single bit. Does not throw an
* exception on overflow and instead 'rolls' over to zero.
*/
public static void increment(byte[] a) {
for (int i = a.length - 1; i >= 0; --i) {
if (++a[i] != 0) {
break;
}
}
}
public static String toBinary(byte b) {
String bString = Integer.toBinaryString(b & 0xFF);
return String.format("%8s", bString).replace(' ', '0');
}
public static String toBinary(byte[] bytes) {
StringBuilder sb = new StringBuilder(16);
for(byte b : bytes) {
if (sb.length() > 0) {
sb.append(' '); //separate byte segments for readability
}
String val = toBinary(b);
sb.append(val);
}
return sb.toString();
}
public static void main(String[] args) {
byte[] b = new byte[]{0, 0, 0, 0}; // integer 0
for(int i = 0; i <= 256; i++) {
System.out.println("b: " + toBinary(b));
increment(b); // effectively b = b + 1;
}
}
}
Running main shows the following output (snipped for brevity):
b: 00000000 00000000 00000000 00000000
b: 00000000 00000000 00000000 00000001
b: 00000000 00000000 00000000 00000010
b: 00000000 00000000 00000000 00000011
b: 00000000 00000000 00000000 00000100
b: 00000000 00000000 00000000 00000101
b: 00000000 00000000 00000000 00000110
b: 00000000 00000000 00000000 00000111
b: 00000000 00000000 00000000 00001000
b: 00000000 00000000 00000000 00001001
b: 00000000 00000000 00000000 00001010
b: 00000000 00000000 00000000 00001011
b: 00000000 00000000 00000000 00001100
b: 00000000 00000000 00000000 00001101
b: 00000000 00000000 00000000 00001110
b: 00000000 00000000 00000000 00001111
b: 00000000 00000000 00000000 00010000
... continued ...
b: 00000000 00000000 00000000 11111110
b: 00000000 00000000 00000000 11111111
b: 00000000 00000000 00000001 00000000
Notice the very last printed bit string. The loop iterator max value is 256 and that number cannot be represented as a single unsigned byte - it requires at least two bytes to represent. As a result, the incrementing of the 2nd-to-last bit string value of:
00000000 00000000 00000000 11111111 (integer value 255)
has to 'overflow' to the next byte to the left (big-endian), and produces the final value:
00000000 00000000 00000001 00000000 (integer value 256)

Shift operator in Java bizarre program output

I came across the following program and it behaving in unexpected manner.
public class ShiftProgram
{
public static void main(String[] args)
{
int i = 0;
while(-1 << i != 0)
i++;
System.out.println(i);
}
}
If we think about this program output, when it reaches 32 while loop condition should return false and terminate and it should print 32.
If you ran this program, it does not print anything but goes into an infinite loop. Any idea whats going on? Thank you in advance.
Have you tried printing out (-1 << i) in the loop to see what's going wrong? If you do, you'll see that it goes:
-1 << 0 = -1
-1 << 1 = -2
-1 << 2 = -4
-1 << 3 = -8
-1 << 4 = -16
-1 << 5 = -32
-1 << 6 = -64
-1 << 7 = -128
-1 << 8 = -256
-1 << 9 = -512
-1 << 10 = -1024
-1 << 11 = -2048
-1 << 12 = -4096
-1 << 13 = -8192
-1 << 14 = -16384
-1 << 15 = -32768
-1 << 16 = -65536
-1 << 17 = -131072
-1 << 18 = -262144
-1 << 19 = -524288
-1 << 20 = -1048576
-1 << 21 = -2097152
-1 << 22 = -4194304
-1 << 23 = -8388608
-1 << 24 = -16777216
-1 << 25 = -33554432
-1 << 26 = -67108864
-1 << 27 = -134217728
-1 << 28 = -268435456
-1 << 29 = -536870912
-1 << 30 = -1073741824
-1 << 31 = -2147483648
-1 << 32 = -1
-1 << 33 = -2
-1 << 34 = -4
-1 << 35 = -8
-1 << 36 = -16
[.. etc ..]
According to the language specification:
The value of n<<s is n left-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.
... so the result will always remain negative.
That document also tells you that:
If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (ยง15.22.1) with the mask value 0x1f. The shift distance actually used is therefore always in the range 0 to 31, inclusive.
So if you use a shift of 32, that's interpreted as a shift of 32 & 0x1f, which is 0. -1 shifted by 0 is still just -1, not 0.
The shift count is interpreted modulo the number of bits in an int (32), and so i << 32 is just i << 0 which is i. Thus, you will never get 0 as the result. My source for that is http://www.janeg.ca/scjp/oper/shift.html. If you do something like int n = -1; while (n != 0) {i++; n <<= 1;}, it will eventually reach 0 like you want.

Categories