I'm using the following code to do the conversion:
public static BitSet fromByte(byte b){
BitSet bs = new BitSet(8);
for (int i=0; i<8; i++){
if ((b & (1 << i)) > 0){
bs.set(i);
}
}
int length = bs.length();
return bs;
}
The output is {0, 3, 4, 5, 6}(from debugger display of the bs) - the indexes where the bits are set. I think this should represent 1001111 with length = 7, but is wrong since 1001111 is 79, not 121. Also I want the length to be 8. Basically I want a bitSet with length 8 which represents correctly any byte number. My expectation would be 01111001 and the display of the debugger to show {1,2,3,4,5,7}
Bits in a byte are numbered right-to-left, not left-to-right. That's why setting bits {0, 3, 4, 5, 6} defines this pattern:
7 6 5 4 3 2 1 0
0 1 1 1 1 0 0 1
{0, 3, 4, 5, 6} is equal to :
(2 ^ 0) | (2 ^ 3) | (2 ^ 4) | (2 ^ 5) | (2 ^ 6)
2^0 = 00000001
2^3 = 00001000
2^4 = 00010000
2^5 = 00100000
2^6 = 01000000
--------------
01111001
Like you guessed, 0 is also the indice of a bit equals to 1. But the bits are ordered from right to left.
You are checking the bits in this order:
00000001 = index 0
00000010 = index 1
00000100 = index 2
00001000 = index 3
etc.
i.e. from right to left, and storing them from left-to-right in the bit set.
The length of the bitset will be as few as bits as necessary to represent the bits you have set. For instance if you set the first three bits, the length will be 2, as only 2 bits are necessary for representation.
The constructor of the BitSet sets its Size, not its length. I suspect they are 2 different concepts.
When I run your code, I get the result I expect. Are you sure of the value you are passing in? Perhaps you are confused about the endianess of your bits? Usually its read from right to left, not left to right (or big endian bitwise order)
Related
I am trying to use an int to represent a register value. I need various parts of the number (in its binary form) to set the state for control lines etc.
My code works fine until I get to number 4096 at which points my boundaries stop behaving.
my boundaries are defined as follows:
bit 1 to bit 2, bit 3- bit 6, 7-11, 12-13, 14-n
I use the following code to convert the boundaries bits into integers:
public int getNToKBits(int leftMostBit, int rightMostBit){
int subBits = (((1 << leftMostBit) - 1) & (value >> (rightMostBit - 1)));
return subBits;
}
but when I try to split the number 4096 into these boundries I get the following:
b: 00, 10, 10000, 0000, 00
d: 0, 2, 64, 0, 0
-I know, there aren't enough bits to make 64!!
what I expect is
b: 00, 10, 00000, 0000, 00
d: 0, 2, 0, 0, 0
It as expected with number less that 4096. Perhaps its a change in the way java treats numbers larger that 4096?
You could define something like this:
public int subBits(int mask, int shift) {
return (value & mask) >> shift;
}
Which would be used like so then:
int[] bits = new int[5];
bits[0] = subBits(0b110000000000000, 13);
bits[1] = subBits(0b001100000000000, 11);
bits[2] = subBits(0b000011111000000, 6);
bits[3] = subBits(0b000000000111100, 2);
bits[4] = subBits(0b000000000000011, 0);
For the field you designate as 7:11:
(((1 << leftMostBit) - 1) & (value >> (rightMostBit - 1)))
((1 << 11) - 1) = 11111111111 binary
(4096 >> (7-1)) = 1000000 binary
((1 << 11) - 1) & (4096 >> (7-1)) = 1000000 binary
This is because you and with the actual (i.e. right-shifted) field bits a mask computed from the leftmost bit number (11), not the number of bits in the field (which is 11-7+1 = 5).
You need to either shift, then mask to the size (not the leftmost bit):
( (value>>(rightmost-1)) & ((1<<(leftmost-rightmost+1))) )
// or equivalently
( ((1<<(leftmost-rightmost+1))) & (value>>(rightmost-1)) )
Or else mask to the leftmost bit before shifting:
( (value & ((1<<leftmost)-1)) >> (rightmost-1) )
And in the latter case if you want to (be able to) use the sign bit (32 by your designation) use >>> for the right shift instead of >>.
Problem formulation: Given a binary code of length l, for every t bits set (l%t=0), if there exists at least one bit of value 1, we add 1 to the result.
My question : How to efficiently get the final result?
For example, we have a binary code 010 110 000, and t=3. Then the final result is 2. Since for 000, there is no bit of value 1. For 110, there exists at least one bit of value 1. We add 1 to the result. For 010, there also exists one bit of value 1. We add 1 to the result. Thus, the final result is 2.
My question is that how to efficiently solve this problem without scanning through every t bits, which causes a time complexity linear with the length of the binary code.
For the counting set problem (calculate how many 1's in a binary code), there are some algorithms which take constant time to solve it by taking a limited number of mask and shift operations such as the MIT HAKMEM Count algorithm.
However, existing algorithms for the traditional counting set problem cannot be used to solve my problem.
Does anyone know some tricks for my problems? You can assume a maximum length of the input binary code if it makes the problem easier to solve.
From comment:
Then you can assume that the input is a binary code of 64-bit integer for this problem.
Here are two different ways to do it.
The first run in O(I/t) and works by testing each set for all 0-bits.
public static int countSets(int setSize, long bits) {
Long mask = (1L << setSize) - 1;
int count = 0;
for (long b = bits; b != 0; b >>>= setSize)
if ((b & mask) != 0)
count++;
return count;
}
The second run in O(log I) and works by collapsing the bits of a set to the right-most bit of the set, then counting bits set.
public static int countSets(int setSize, int bitCount, long bits) {
long b = bits, mask = 1;
for (int i = 1; i < setSize; i++)
b |= bits >>> i;
for (int i = setSize; i < bitCount; i <<= 1)
mask |= mask << i;
return Long.bitCount(b & mask);
}
Further explanation
The first method builds a mask for the set, e.g. with t = 3, the mask is 111.
It then shifts the value to the right, t bits at a time, e.g. with input = 010 110 000 and t = 3, you get:
mask = 111
b = 010 110 000 -> b & mask = 000 -> don't count
b = 010 110 -> b & mask = 110 -> count
b = 010 -> b & mask = 010 -> count
result: 2
The second method first merge bits to the right-most bit of the sets, e.g. with input = 010 110 000 and t = 3, you get:
bits = 010 110 000
bits >> 1 = 001 011 000
bits >> 2 = 000 101 100
b (OR'd) = 011 111 100
It then builds a mask for only checking right-most bits, and then applies mask and counts the bits set:
mask = 001 001 001
b & mask = 001 001 000
result: 2
This question already has answers here:
What are bitwise shift (bit-shift) operators and how do they work?
(10 answers)
Closed 4 years ago.
I am trying to understand the shift operators and couldn't get much.
When I tried to execute the below code
System.out.println(Integer.toBinaryString(2 << 11));
System.out.println(Integer.toBinaryString(2 << 22));
System.out.println(Integer.toBinaryString(2 << 33));
System.out.println(Integer.toBinaryString(2 << 44));
System.out.println(Integer.toBinaryString(2 << 55));
I get the below
1000000000000
100000000000000000000000
100
10000000000000
1000000000000000000000000
Could somebody please explain?
System.out.println(Integer.toBinaryString(2 << 11));
Shifts binary 2(10) by 11 times to the left. Hence: 1000000000000
System.out.println(Integer.toBinaryString(2 << 22));
Shifts binary 2(10) by 22 times to the left. Hence : 100000000000000000000000
System.out.println(Integer.toBinaryString(2 << 33));
Now, int is of 4 bytes,hence 32 bits. So when you do shift by 33, it's equivalent to shift by 1. Hence : 100
2 from decimal numbering system in binary is as follows
10
now if you do
2 << 11
it would be , 11 zeros would be padded on the right side
1000000000000
The signed left shift operator "<<" shifts a bit pattern to the left, and the signed right shift operator ">>" shifts a bit pattern to the right. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension [..]
left shifting results in multiplication by 2 (*2) in terms or arithmetic
For example
2 in binary 10, if you do <<1 that would be 100 which is 4
4 in binary 100, if you do <<1 that would be 1000 which is 8
Also See
absolute-beginners-guide-to-bit-shifting
Right and Left shift work on same way here is How Right Shift works;
The Right Shift:
The right shift operator, >>, shifts all of the bits in a value to the right a specified number of times. Its general form:
value >> num
Here, num specifies the number of positions to right-shift the value in value. That is, the >> moves all of the bits in the specified value to the right the number of bit positions specified by num.
The following code fragment shifts the value 32 to the right by two positions, resulting in a being set to 8:
int a = 32;
a = a >> 2; // a now contains 8
When a value has bits that are “shifted off,” those bits are lost. For example, the next code fragment shifts the value 35 to the right two positions, which causes the two low-order bits to be lost, resulting again in a being set to 8.
int a = 35;
a = a >> 2; // a still contains 8
Looking at the same operation in binary shows more clearly how this happens:
00100011 35 >> 2
00001000 8
Each time you shift a value to the right, it divides that value by two—and discards any remainder. You can take advantage of this for high-performance integer division by 2. Of course, you must be sure that you are not shifting any bits off the right end.
When you are shifting right, the top (leftmost) bits exposed by the right shift are filled in with the previous contents of the top bit. This is called sign extension and serves to preserve the sign of negative numbers when you shift them right. For example, –8 >> 1 is –4, which, in binary, is
11111000 –8 >>1
11111100 –4
It is interesting to note that if you shift –1 right, the result always remains –1, since sign extension keeps bringing in more ones in the high-order bits.
Sometimes it is not desirable to sign-extend values when you are shifting them to the right. For example, the following program converts a byte value to its hexadecimal string representation. Notice that the shifted value is masked by ANDing it with 0x0f to discard any sign-extended bits so that the value can be used as an index into the array of hexadecimal characters.
// Masking sign extension.
class HexByte {
static public void main(String args[]) {
char hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
byte b = (byte) 0xf1;
System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
}
}
Here is the output of this program:
b = 0xf1
I believe this might Help:
System.out.println(Integer.toBinaryString(2 << 0));
System.out.println(Integer.toBinaryString(2 << 1));
System.out.println(Integer.toBinaryString(2 << 2));
System.out.println(Integer.toBinaryString(2 << 3));
System.out.println(Integer.toBinaryString(2 << 4));
System.out.println(Integer.toBinaryString(2 << 5));
Result
10
100
1000
10000
100000
1000000
Edited:
Must Read This (how-do-the-bitwise-shift-operators-work)
I think it would be the following, for example:
Signed left shift
[ 2 << 1 ] is => [10 (binary of 2) add 1 zero at the end of the binary string] Hence 10 will be 100 which becomes 4.
Signed left shift uses multiplication...
So this could also be calculated as 2 * (2^1) = 4.
Another example [2 << 11] = 2 *(2^11) = 4096
Signed right shift
[ 4 >> 1 ] is => [100 (binary of 4) remove 1 zero at the end of the binary string] Hence 100 will be 10 which becomes 2.
Signed right shift uses division...
So this could also be calculated as 4 / (2^1) = 2
Another example [4096 >> 11] = 4096 / (2^11) = 2
It will shift the bits by padding that many 0's.
For ex,
binary 10 which is digit 2 left shift by 2 is 1000 which is digit 8
binary 10 which is digit 2 left shift by 3 is 10000 which is digit 16
Signed left shift
Logically
Simple if 1<<11 it will tends to 2048 and 2<<11 will give 4096
In java programming
int a = 2 << 11;
// it will result in 4096
2<<11 = 2*(2^11) = 4096
The shift can be implement with data types (char, int and long int). The float and double data connot be shifted.
value= value >> steps // Right shift, signed data.
value= value << steps // Left shift, signed data.
The typical usage of shifting a variable and assigning back to the variable can be
rewritten with shorthand operators <<=, >>=, or >>>=, also known in the spec as Compound Assignment Operators.
For example,
i >>= 2
produces the same result as
i = i >> 2
I try to learn BitSet collection in java. I have read that it uses bits inside.
Each * component of the bit set has a {#code boolean} value
I wrote a small application:
BitSet bitSet = new BitSet();
bitSet.set(9);
bitSet.set(5);
bitSet.set(3);
System.out.println(bitSet);
System.out.println(Arrays.toString(bitSet.toByteArray()));
I was wondered that I can put value different from 1 and 0.
Also I don't understand the output:
{3, 5, 9}
[40, 2]
Please explain me the usage of this collection?
You set the bits number 3, 5 and 9:
byte# 1 0
index … 9 8 7 6 5 4 3 2 1 0
value … 1 0 0 0 1 0 1 0 0 0
Binary 10 is decimal 2 (2¹ = 2).
Binary 00101000 is decimal 40 (2³ + 2⁵ = 8 + 32 = 40).
BitSet logically represents a "vector of bits that grows as needed" (javadoc).
When you create it via new BitSet(), you have all bits set to 0 (false).
0 5 10
| | |
000000000000... (virtually infinite sequence)
Using set(x) you set to 1 (true) the bit at position x (where the first position is 0); e.g. in your code you enable bits 3, 5 and 9.
0 5 10
| | |
000101000100...
toString() reports the list of bits set to 1, i.e. 3, 5 and 9 in the example.
toByteArray() converts the contents of the BitSet to a sequence of byte values, each containing the value of 8 contiguous bits, in little-endian order (i.e. starting from least indices in the BitSet). The output {40, 2} in your example comes from:
7 0 15 8 <- position in BitSet
| | | |
{00101000 , 00000010} <- toByteArray(), binary
| |
{ 40 , 2 } <- toByteArray(), decimal
Hope this helps.
BitSet.set(int bitIndex) sets the bit at the specified index to true.
So bitSet.set(9); flips bit number 9 to 1
On output:
System.out.println(bitSet); prints the result of toString which is according to JavaDoc:
for every index for which this BitSet contains a bit in the set state, the decimal representation of that index is included in the result. S
Arrays.toString(bitSet.toByteArray()) prints byte representation of BitSet.
Step by step, it splits your binary set: 1000101000
to bytes: 10 00101000
which is 2 and 40 in decimal.
This question already has answers here:
What are bitwise shift (bit-shift) operators and how do they work?
(10 answers)
Closed 4 years ago.
I am trying to understand the shift operators and couldn't get much.
When I tried to execute the below code
System.out.println(Integer.toBinaryString(2 << 11));
System.out.println(Integer.toBinaryString(2 << 22));
System.out.println(Integer.toBinaryString(2 << 33));
System.out.println(Integer.toBinaryString(2 << 44));
System.out.println(Integer.toBinaryString(2 << 55));
I get the below
1000000000000
100000000000000000000000
100
10000000000000
1000000000000000000000000
Could somebody please explain?
System.out.println(Integer.toBinaryString(2 << 11));
Shifts binary 2(10) by 11 times to the left. Hence: 1000000000000
System.out.println(Integer.toBinaryString(2 << 22));
Shifts binary 2(10) by 22 times to the left. Hence : 100000000000000000000000
System.out.println(Integer.toBinaryString(2 << 33));
Now, int is of 4 bytes,hence 32 bits. So when you do shift by 33, it's equivalent to shift by 1. Hence : 100
2 from decimal numbering system in binary is as follows
10
now if you do
2 << 11
it would be , 11 zeros would be padded on the right side
1000000000000
The signed left shift operator "<<" shifts a bit pattern to the left, and the signed right shift operator ">>" shifts a bit pattern to the right. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension [..]
left shifting results in multiplication by 2 (*2) in terms or arithmetic
For example
2 in binary 10, if you do <<1 that would be 100 which is 4
4 in binary 100, if you do <<1 that would be 1000 which is 8
Also See
absolute-beginners-guide-to-bit-shifting
Right and Left shift work on same way here is How Right Shift works;
The Right Shift:
The right shift operator, >>, shifts all of the bits in a value to the right a specified number of times. Its general form:
value >> num
Here, num specifies the number of positions to right-shift the value in value. That is, the >> moves all of the bits in the specified value to the right the number of bit positions specified by num.
The following code fragment shifts the value 32 to the right by two positions, resulting in a being set to 8:
int a = 32;
a = a >> 2; // a now contains 8
When a value has bits that are “shifted off,” those bits are lost. For example, the next code fragment shifts the value 35 to the right two positions, which causes the two low-order bits to be lost, resulting again in a being set to 8.
int a = 35;
a = a >> 2; // a still contains 8
Looking at the same operation in binary shows more clearly how this happens:
00100011 35 >> 2
00001000 8
Each time you shift a value to the right, it divides that value by two—and discards any remainder. You can take advantage of this for high-performance integer division by 2. Of course, you must be sure that you are not shifting any bits off the right end.
When you are shifting right, the top (leftmost) bits exposed by the right shift are filled in with the previous contents of the top bit. This is called sign extension and serves to preserve the sign of negative numbers when you shift them right. For example, –8 >> 1 is –4, which, in binary, is
11111000 –8 >>1
11111100 –4
It is interesting to note that if you shift –1 right, the result always remains –1, since sign extension keeps bringing in more ones in the high-order bits.
Sometimes it is not desirable to sign-extend values when you are shifting them to the right. For example, the following program converts a byte value to its hexadecimal string representation. Notice that the shifted value is masked by ANDing it with 0x0f to discard any sign-extended bits so that the value can be used as an index into the array of hexadecimal characters.
// Masking sign extension.
class HexByte {
static public void main(String args[]) {
char hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
byte b = (byte) 0xf1;
System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
}
}
Here is the output of this program:
b = 0xf1
I believe this might Help:
System.out.println(Integer.toBinaryString(2 << 0));
System.out.println(Integer.toBinaryString(2 << 1));
System.out.println(Integer.toBinaryString(2 << 2));
System.out.println(Integer.toBinaryString(2 << 3));
System.out.println(Integer.toBinaryString(2 << 4));
System.out.println(Integer.toBinaryString(2 << 5));
Result
10
100
1000
10000
100000
1000000
Edited:
Must Read This (how-do-the-bitwise-shift-operators-work)
I think it would be the following, for example:
Signed left shift
[ 2 << 1 ] is => [10 (binary of 2) add 1 zero at the end of the binary string] Hence 10 will be 100 which becomes 4.
Signed left shift uses multiplication...
So this could also be calculated as 2 * (2^1) = 4.
Another example [2 << 11] = 2 *(2^11) = 4096
Signed right shift
[ 4 >> 1 ] is => [100 (binary of 4) remove 1 zero at the end of the binary string] Hence 100 will be 10 which becomes 2.
Signed right shift uses division...
So this could also be calculated as 4 / (2^1) = 2
Another example [4096 >> 11] = 4096 / (2^11) = 2
It will shift the bits by padding that many 0's.
For ex,
binary 10 which is digit 2 left shift by 2 is 1000 which is digit 8
binary 10 which is digit 2 left shift by 3 is 10000 which is digit 16
Signed left shift
Logically
Simple if 1<<11 it will tends to 2048 and 2<<11 will give 4096
In java programming
int a = 2 << 11;
// it will result in 4096
2<<11 = 2*(2^11) = 4096
The shift can be implement with data types (char, int and long int). The float and double data connot be shifted.
value= value >> steps // Right shift, signed data.
value= value << steps // Left shift, signed data.
The typical usage of shifting a variable and assigning back to the variable can be
rewritten with shorthand operators <<=, >>=, or >>>=, also known in the spec as Compound Assignment Operators.
For example,
i >>= 2
produces the same result as
i = i >> 2