I need to switch the first half and the second half of a byte: Make 0011 0101 to 0101 0011 for example
I thought it might work this way:
For example, i have 1001 1100
i bitshift to the left 4 times and get 1111 1001(because if the first bit is a 1 the others become a one too)
i bitshift to the right 4 times and get 1100 0000(the second half of the byte gets filled with 0s)
i don't want 1111 1001 but 0000 1001 so i do 0x00001111 & 1111 1001 (which filters the frist 4 bits) to make 1111 1001 to 0000 1001
then i add everything up:
0000 1001 + 1100 0000 = 1100 1001
I got this:
bytes[i] = (byte) (( 0x00001111 & (bytes[i] >> 4)) + (bytes[i] << 4)
);
here is one output: 11111111 to 00000001
I do not really understand why this is happening, I know the binary System and I think I know how bitshifting works but I can't explain this one.
Sorry for bad english :)
Be careful with the >>> operation, which shifts the sign bits without sign extending so zero bits will fill in on the left. The problem is that it is an integer operation. The >> works the same way except it sign extends thru the int.
int i = -1;
i >>>= 30;
System.out.println(i); // prints 3 as expected.
byte b = -1;
b >>>= 6;
System.out.printnln(b); // prints -1 ???
The byte is still -1 because byte b = -1 was shifted as though it was an int then reassigned to a byte. So the byte remained negative. To get 3, you would need to do something that seems strange, like the following.
byte b = -1;
b >>>=30;
System.out.println(b); // prints 3
So to do your swap you need to do the following;
byte b = 0b10100110;
b = (byte)(((b>>>4)&0xF)|(b<<4));
The 0xF mask, masks off those lingering high order bits left over from the conversion from integer back to byte.
I'm not sure about the syntax for bit manipulation in Java, although here's how you can do it.
bitmask = 0x1111;
firstHalf = ((bytes[i] >> 4) & bitmask);
secondHalf = ((bytes[i] & bitmask) << 4)
result = firstHalf | secondHalf;
I don't want 1111 1001 but 0000 1001
If so, you need to use shift right zero fill operator(>>>) instead of preserving sign of the number.
I don't think the formula found works properly.
public byte reverseBitsByte(byte x) {
int intSize = 8;
byte y=0;
for(int position=intSize-1; position>0; position--){
y+=((x&1)<<position);
x >>= 1;
}
return y;
}
static int swapBits(int a) {
// Написать решение сюда ↓
int right = (a & 0b00001111);
right= (right<<4);
int left = (a & 0b11110000);
left = (left>>4);
return (right | left);
}
Related
This question is related to but it is different in understanding how the code actually works. More precisely, I do not understand how numberOfTrailingZeros(int i) in java 8 here compute the final result. The code is as follows
public static int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - ((i << 1) >>> 31);
}
Now I understand the purpose of the shift operations from 16 to 2, but won't n have already the number of trailing zeros by the last shift operation:
y = i << 2; if (y != 0) { n = n - 2; i = y; }.
That is I do not understand the purpose of this particular line
n - ((i << 1) >>> 31);
why do we need that when n has already the right value?
Can anyone give a detailed example of what is going on?
Thanks!
I will try to explain the algorithm. It is a bit optimized, but I'll start with a (hopefully) more simplified approach.
It is used to determine the number of trailing zero bits of a 32 bit number, that is, how many zeros are on the right side (assuming most significant bit on left). The main idea is to divide the field in two half: if the right one is all zero we add the number of bits in the right half to the result and continue examining the left one (again dividing it); if the right one is not all zero, we can ignore the left one and continue examining the right one (adding nothing to the result).
Example: 0000 0000 0000 0010 0000 0000 0000 0000 (0x0002 0000)
first step (not java code, all numbers base 2, result is decimal):
i = 0000 0000 0000 0010 0000 0000 0000 0000
left = 0000 0000 0000 0010
right = 0000 0000 0000 0000
result = 0
since right is zero, we add 16 (actual number of bits in right part) to the result and continue examining the left part
second step:
i = 0000 0000 0000 0010 // left from previous
left = 0000 0000
right = 0000 0010
result = 16
now right is not zero, so we add nothing to result and continue with right part
third step:
i = 0000 0010 // right from previous
left = 0000
right = 0010
result = 16
right is not zero, nothing added to result, continue with right part
4th step:
i = 0010 // right from previous
left = 00
right = 10
result = 16
5th step:
i = 10 // right from previous
left = 1
right = 0
result = 16
now right is zero, so we add 1 (number of bits in right part) and there is nothing else to divide (that is the return line off original code)
result = 17
Optimizations: instead of having the left and the right part, the algorithm only examines the left left x-most bits of the number and just shift the right part into the left if the right one is not zero, example for first step:
y = i << 16; if (y != 0) { ... i = y;}
and, to avoid having an else part (I think), it starts the result with 31 (sum of all part lengths 1+2+4+8+16) and subtracts the bit count if the right side (after shifting the now left one) is not zero. Again for the first step:
y = i << 16; if (y != 0) { n = n - 16; ....}
Second optimization, last step, instead of
y = i << 1; if (y != 0) { n = n - 1; /* i = y not needed since we are done*/ }
return n;
it does just
return n - ((i << 1) >>> 31);
here ((i << 1) >>>31) is shifting the second bit (second leftmost, second highest bit) of i to leftmost position (eliminating the first bit) and then shifting it to rightmost position, that is, resulting in 0 if the second bit is zero, 1 otherwise. Which is then subtracted from the result (to undo the sum 31 from the beginning).
The first (leftmost) bit need not be directly examined. It only matters if all other bits are zero, that is, the number is 0, checked at the very beginning (if (i == 0) return 32;) or it is -1 in which case the initial value of result is returned: 31.
public int tobinary(int x)
{
int count = 0;
while(x!=0)
{
x=(x&(x<<1)); //how this stuff is working
count++;
}
return count;
}
the above code is working fine but actually i did copy and paste.so i just want to know how that line of code which i mentioned above is working.it would be a great help for me.
for example i am giving i/p as 7 the binary format for this is 0111 so our answer will be 3 but how ?
As we know, the << operator shifts all bits in its operand to the left, here by 1. Also, the & operator performs a bitwise-and on all bits of both its operands.
When will x not be 0? When the bitwise-and operation finds 2 bits that are both set in both operands. The only time that this will be true is when there are 2 or more consecutive 1 bits in x and x << 1.
x : 0000 0111
x << 1: 0000 1110
-----------------
&: 0000 0110
count = 1
If it's not 0, then there are at least 2 consecutive 1 bits in the number, and the (maximum) number of consecutive 1 bits in the number has been reduced by 1. Because we entered the loop in the first place, count it and try again. Eventually there won't be any more consecutive 1 bits, so we exit the loop with the correct count.
x : 0000 0110
x << 1: 0000 1100
-----------------
&: 0000 0100
count = 2
x : 0000 0100
x << 1: 0000 1000
-----------------
&: 0000 0000
count = 3, exit loop and return.
x = (x & (x << 1)) is performed enough times to eliminate the longest consecutive groups of 1 bits. Each loop iteration reduces each consecutive group of 1s by one because the number is logically ANDed with itself shifted left by one bit. This continues until no consecutive group of 1s remains.
To illustrate it for number 110111101:
110111101 // initial x, longest sequence 4
1101111010 // x << 1, count 1
100111000 // new x, longest sequence 3
1001110000 // x << 1, count 2
110000 // new x, longest sequence 2
1100000 // x << 1, count 3
100000 // new x, longest sequence 1
1000000 // x << 1, count 4
0 // new x, end of loop
Do note that since Java 7 it's handy to declare binary literals with int input = 0b110111101.
<< (left shift) : Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand.
i.e. x<<1 shifts the value bit from right to left by 1 and in the unit position add 0. So, lets say for x=7, bit representation will be 111. Performing x << 1 will return 110 i.e. discarded the head element, shifted the bits to left and added 0 in the end.
This while loop can be broken down into below iteration for initial value of x=7
iteration 1) 111 & 110 =110
iteration 2) 110 & 100 =100
iteration 3) 100 & 000 =000
As value of x is 0, no more iteration
Hope this explains the behaviour of this code. You can put System.out.println(Integer.toBinaryString(x)); to see the change in bit value of x yourself
So what happens is, for each iteration in the while loop,
x = x (AND operator) (2 * x).
For example, when x = 7
count = 0
Iteration 1:
//x = 7 & 14 which results in 6 ie
0111
1110 (AND)
-------
0110 => 6
-------
count = 1
Iteration 2:
//x = 6 & 12 results in 4
0110
1100 AND
-------
0100 => 4
-------
count = 2
Iteration 3:
// x = 4 & 8 results in 0
0100
1000 AND
-----
0000
-----
count = 3
That's how you get 3 for 7
The problem is to reverse the bits of a 32 bit unsigned integer (since Java doesn't have unsigned integers we use long).
Here are two versions of my code. I have two concerns:
(1) why my 1st and 2nd solution don't return the same value (correct or not)
(2) where my 1st and 2nd solution went wrong in not getting the correct answer
//reverse(3) returns 0
public static long reverse(long a) {
long numBits = 32;
long finalResult = 0;
for(int i = 0; i < numBits; i++){
long ithBit = a & (1 << i);
finalResult = finalResult + ithBit * (1 << (numBits - i - 1));
}
return finalResult;
}
Second version:
//reverse(3) return 4294967296
public static long reverse(long a) {
long numBits = 32L;
long finalResult = 0L;
for(long i = 0L; i < numBits; i++){
long ithBit = a & (1L << i);
finalResult = finalResult + ithBit * (1L << (numBits - i - 1L));
}
return finalResult;
}
This code (the solution) returns the correct answer, however:
//reverse(3) returns 3221225472
public static long reverse(long A) {
long rev = 0;
for (int i = 0; i < 32; i++) {
rev <<= 1;
if ((A & (1 << i)) != 0)
rev |= 1;
}
return rev;
}
Thanks!
Let's have a look at your values as you iterate. For clarification, we'll have a look at the intermediate values, so we'll change code to:
int n = (1 << (numBits - i - 1));
long m = ithBit * n;
finalResult = finalResult + m;
Your starting value is 3:
a = 0000 0000 0000 0000 0000 0000 0000 0011
First loop iteration (i = 0):
ithBit = 00000000 00000000 00000000 00000001
n = 11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000
m = 11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000
finalResult = 11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000
Second loop iteration (i = 1):
ithBit = 00000000 00000000 00000000 00000010
n = 01000000 00000000 00000000 00000000
m = 10000000 00000000 00000000 00000000
finalResult = 00000000 00000000 00000000 00000000
As you can see, the first iterate sets n = 1 << 31, which is -2147483648. In your second version you do n = 1L << 31, which is 2147483648, and that's why your two versions give different results.
As you can also see, you definitely don't want to do the m = ithBit * n part.
Have a look at your number by printing them yourself, and you'll figure it out.
BTW, here's my version. If you have trouble understanding it, try printing the intermediate values to see what's going on.
public static long reverse4(long a) {
long rev = 0;
for (int i = 0; i < 32; i++, a >>= 1)
rev = (rev << 1) | (a & 1);
return rev;
}
since Java doesn't have unsigned integers we use long.
That's generally unecessary since all arithmetic operations except division and comparison result in identical bit patterns for unsigned and signed numbers in two's complement representation, which java uses. And for the latter two ops Integer.divideUnsigned(int, int) and Integer.compareUnsigned(int, int) are available.
The problem is to reverse the bits of a 32 bit unsigned integer
There's Integer.reverse(int)
Relevant docs, spending some time reading them is highly recommended.
Problem with your both examples is that the "i-th bit" isn't a 0 or 1 but rather masked off. In either case, the 31'th bit is 0x8000_0000. In the first case, this is an int, so it is negative, and when converted to a long it stays negative. In the second case it is already a long, so it stays positive. To fix it so it does what you intended, do:
ithBit = (a >>> i) & 1;
By the way, using long is silly; unsigned vs. signed makes no difference as long as you understand that there are two types of shifts in Java.
By the way, all three examples are terrible. If you are doing bit manipulation, you want speed, right? (Why else bother with bits?)
This is how to do it right (not mine, stolen from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits):
a = ((a >>> 1) & 0x55555555) | ((a & 0x55555555) << 1);
a = ((a >>> 2) & 0x33333333) | ((a & 0x33333333) << 2);
a = ((a >>> 4) & 0x0F0F0F0F) | ((a & 0x0F0F0F0F) << 4);
a = ((a >>> 8) & 0x00FF00FF) | ((a & 0x00FF00FF) << 8);
a = ( a >>> 16 ) | ( a << 16);
In both versions you have a logic problem here:
ithBit * (1 << (numBits - i - 1));
because the two numbers multiply to the same bit pattern of bit 31 (the 32nd) being set.
In version 1, the amount added is -2^31 if bit 0 is set because you're bit-shifting an int so the bit-shifted result is int which represents -2^31 as the high bit being set, or 2^31 for every other bit, which is possible due to the auto-cast to long of the result. You have two of each kind of bit (0 and non 0) so the result is zero.
Version 2 has the same problem, but without the negative int issue because you're bit shifting a long. Each bit that is 1 will add 2^31. The number 3 has 2 bits set, so your result is 2 * 2^31 (or 2^32) which is 4294967296.
To fix your logic, use version 2 but remove the multiply by ithBit.
I have this statement:
Assume the bit value of byte x is 00101011. what is the result of x>>2?
How can I program it and can someone explain me what is doing?
Firstly, you can not shift a byte in java, you can only shift an int or a long. So the byte will undergo promotion first, e.g.
00101011 -> 00000000000000000000000000101011
or
11010100 -> 11111111111111111111111111010100
Now, x >> N means (if you view it as a string of binary digits):
The rightmost N bits are discarded
The leftmost bit is replicated as many times as necessary to pad the result to the original size (32 or 64 bits), e.g.
00000000000000000000000000101011 >> 2 -> 00000000000000000000000000001010
11111111111111111111111111010100 >> 2 -> 11111111111111111111111111110101
The binary 32 bits for 00101011 is
00000000 00000000 00000000 00101011, and the result is:
00000000 00000000 00000000 00101011 >> 2(times)
\\ \\
00000000 00000000 00000000 00001010
Shifts the bits of 43 to right by distance 2; fills with highest(sign) bit on the left side.
Result is 00001010 with decimal value 10.
00001010
8+2 = 10
When you shift right 2 bits you drop the 2 least significant bits. So:
x = 00101011
x >> 2
// now (notice the 2 new 0's on the left of the byte)
x = 00001010
This is essentially the same thing as dividing an int by 2, 2 times.
In Java
byte b = (byte) 16;
b = b >> 2;
// prints 4
System.out.println(b);
These examples cover the three types of shifts applied to both a positive and a negative number:
// Signed left shift on 626348975
00100101010101010101001110101111 is 626348975
01001010101010101010011101011110 is 1252697950 after << 1
10010101010101010100111010111100 is -1789571396 after << 2
00101010101010101001110101111000 is 715824504 after << 3
// Signed left shift on -552270512
11011111000101010000010101010000 is -552270512
10111110001010100000101010100000 is -1104541024 after << 1
01111100010101000001010101000000 is 2085885248 after << 2
11111000101010000010101010000000 is -123196800 after << 3
// Signed right shift on 626348975
00100101010101010101001110101111 is 626348975
00010010101010101010100111010111 is 313174487 after >> 1
00001001010101010101010011101011 is 156587243 after >> 2
00000100101010101010101001110101 is 78293621 after >> 3
// Signed right shift on -552270512
11011111000101010000010101010000 is -552270512
11101111100010101000001010101000 is -276135256 after >> 1
11110111110001010100000101010100 is -138067628 after >> 2
11111011111000101010000010101010 is -69033814 after >> 3
// Unsigned right shift on 626348975
00100101010101010101001110101111 is 626348975
00010010101010101010100111010111 is 313174487 after >>> 1
00001001010101010101010011101011 is 156587243 after >>> 2
00000100101010101010101001110101 is 78293621 after >>> 3
// Unsigned right shift on -552270512
11011111000101010000010101010000 is -552270512
01101111100010101000001010101000 is 1871348392 after >>> 1
00110111110001010100000101010100 is 935674196 after >>> 2
00011011111000101010000010101010 is 467837098 after >>> 3
>> is the Arithmetic Right Shift operator. All of the bits in the first operand are shifted the number of places indicated by the second operand. The leftmost bits in the result are set to the same value as the leftmost bit in the original number. (This is so that negative numbers remain negative.)
Here's your specific case:
00101011
001010 <-- Shifted twice to the right (rightmost bits dropped)
00001010 <-- Leftmost bits filled with 0s (to match leftmost bit in original number)
public class Shift {
public static void main(String[] args) {
Byte b = Byte.parseByte("00101011",2);
System.out.println(b);
byte val = b.byteValue();
Byte shifted = new Byte((byte) (val >> 2));
System.out.println(shifted);
// often overloked are the methods of Integer
int i = Integer.parseInt("00101011",2);
System.out.println( Integer.toBinaryString(i));
i >>= 2;
System.out.println( Integer.toBinaryString(i));
}
}
Output:
43
10
101011
1010
byte x = 51; //00101011
byte y = (byte) (x >> 2); //00001010 aka Base(10) 10
You can't write binary literals like 00101011 in Java so you can write it in hexadecimal instead:
byte x = 0x2b;
To calculate the result of x >> 2 you can then just write exactly that and print the result.
System.out.println(x >> 2);
You can use e.g. this API if you would like to see bitString presentation of your numbers. Uncommons Math
Example (in jruby)
bitString = org.uncommons.maths.binary.BitString.new(java.math.BigInteger.new("12").toString(2))
bitString.setBit(1, true)
bitString.toNumber => 14
edit: Changed api link and add a little example
00101011 = 43 in decimal
class test {
public static void main(String[] args){
int a= 43;
String b= Integer.toBinaryString(a >> 2);
System.out.println(b);
}
}
Output:
101011 becomes 1010
I'm attempting to make a customized buffer that's going to be using a List<Byte> and currently I've only gotten as far as a single method before it completely broke down on me, and I'm not sure exactly why. I've been referencing the Source code of the DataOutputStream and DataInputStream classes to make sure that I'm reading/writing the data correctly.
I must be doing something wrong.
private List<Byte> buffer = new ArrayList<>();
public void writeInt(int value) {
buffer.add((byte)((value >>> 24) & 0xFF));
buffer.add((byte)((value >>> 16) & 0xFF));
buffer.add((byte)((value >>> 8) & 0xFF));
buffer.add((byte)((value >>> 0) & 0xFF));
}
public void readInt() {
int ch1 = buffer.get(0);
int ch2 = buffer.get(1);
int ch3 = buffer.get(2);
int ch4 = buffer.get(3);
System.out.println("CH1: " + ch1);
System.out.println("CH2: " + ch2);
System.out.println("CH3: " + ch3);
System.out.println("CH4: " + ch4);
System.out.println("===============");
int value = ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
System.out.println("Value: " + value);
}
If I write a small value(Anything from 0->127), it's perfectly fine, however the moment I get to 128, all hell breaks lose, here's the output of 127vs128
#writeInt(127)
CH1: 0
CH2: 0
CH3: 0
CH4: 127
===============
Value: 127
#writeInt(128)
CH1: 0
CH2: 0
CH3: 0
CH4: -128
===============
Value: 128
And just for some more (I don't understand it) examples, here's a large number.
#writeInt(999999999)
CH1: 59
CH2: -102
CH3: -55
CH4: -1
===============
Value: 983156991
I'm honestly not sure where I'm going wrong, hopefully someone can tell me.
EDIT: I also thought it could be because I'm getting the byte as an int, and then trying to do the math, so I changed it up, but it didn't change the result at all. Modification example:
public void readInt() {
int ch1 = buffer.get(0) << 24;
int ch2 = buffer.get(1) << 16;
int ch3 = buffer.get(2) << 8;
int ch4 = buffer.get(3) << 0;
System.out.println("CH1: " + ch1);
System.out.println("CH2: " + ch2);
System.out.println("CH3: " + ch3);
System.out.println("CH4: " + ch4);
System.out.println("===============");
int value = (ch1 + ch2 + ch3 + ch4);
System.out.println("Value: " + value);
}
The type byte in Java is signed, like all primitive types with number semantics (char is the sole exception, but I wouldn't call char number semantics anyway). And Java, like the vast majority of devices, uses two's complement to store values.
Therefore the value range of byte is -128 to 127, here's a few of the corresponding 2's complement bit patterns that would be stored in a byte:
-128 -> 1000 0000
-127 -> 1000 0001
-2 -> 1111 1110
-1 -> 1111 1111
0 -> 0000 0000
1 -> 0000 0001
126 -> 0111 1110
127 -> 0111 1111
When you cast byte to int, and that's what happens implicitly when you do buffer.get() because you do arithmetic with the return value, it happens in a sign-extending way - that's how it's defined in Java.
In other words:
(int) 128 -> 128 (0000 0000 0000 0000 0000 0000 1000 0000)
(byte) (int) 128 -> -128 (---- ---- ---- ---- ---- ---- 1000 0000)
(int) (byte) (int) 128 -> -128 (1111 1111 1111 1111 1111 1111 1000 0000)
You want to negate the effects of sign-extension explicitly. You can do so by using & 0xFF before you shift the value. The corresponding part of your readInt() method should be like this:
int ch1 = buffer.get(0) & 0xFF;
int ch2 = buffer.get(1) & 0xFF;
int ch3 = buffer.get(2) & 0xFF;
int ch4 = buffer.get(3) & 0xFF;