I have a simple question - I need to write a function for my program to change the 3rd bit of a given byte.
I wrote those lines :
public byte turnOn(Byte value)
{
int flag = 8;
value = (byte) (value | flag);
return value;
}
I'm not sure if it's the right way to do that, because I saw also this way (with which I am unfamiliar)
value = (byte) (value | (1 << 2) );
which way is better, and what does 1 << 2 means (2 means the third bit, but what is the 1 )
Thanks!
1 << 2 means 1 shifted two bits to the left. Since shifting left by one bit is similar to multiplying by two, this gives 4. In binary, this is
00000100
i.e. the 3rd bit from the right is set.
The constant 1 is used since that number only has a single bit set - the rightmost bit. After shifting left, only the 3rd bit (from the right) is set:
00000001 original value
00000010 after shifting left once
00000100 after shifting left again
I prefer using 1 << 2 instead of a constant like 8, as it makes it clearer which bit is being set. It also prevents you inadvertently using a constant that has multiple bits set - unless you actually want that, of course. Even then, it's clearer in my opinion to add together several bits, for clarity:
final int bitsToSet = (1 << 2) + (1 << 5);
4 (or 1 << 2) is 00000100 in binary¹. ORing with this mask sets the third least significant bit (or the fifth significant bit in a byte).
8 (or 1 << 3) is 00001000 in binary, so you're setting the fourth least significant bit (or the fifth one of a byte).
It does not matter which expression you use, the shifting just makes it clear you're using a bitmask. Alternatively, you can use the hexadecimal 0x04 which is (imho) easier to translate to the binary bitmask.
1 The leading zeros do not change the value, but should simplify counting the position of the set bit in a byte.
(1 << 2) will left-shift the value 1 twice. Generically, (x << y) means x * (2 ^ y). So 1 << 2 is 4.
Generally speaking, it should not matter whether you use the bit-shift or bit-set method. The compiler should optimize either way.
That said, are you looking for the 3rd bit, indexed from 0 or indexed from 1? If you're looking for the third-right-most bit starting at index 1, you want your flag to be 4 instead of 8. Additionally, the | operator is the set-value operator. If you literally want to "change" the bit, you want to use the ^ operator -- bitwise XOR -- which is the toggle-value operator.
Does that make sense?
Related
private static long permute(byte[] table, int srcWidth, long src) {
long dst = 0;
for (int i=0; i<table.length; i++) {
int srcPos = srcWidth - table[i];
dst = (dst<<1) | (src>>srcPos & 0x01);
}
return dst;
}
here dst = (dst<<1) | (src>>srcPos & 0x01); how does this work?? i am assuming | is an OR operator?
One way to think about the bitwise "and" and "or" operations are as ways to set (turn on) and reset (turn off) bits in your result.
You think as one operand as your "mask" - ones and zeros that represent what needs to be set or reset. The other operand is going to be "masked" by that "mask". In the following way:
If the operator is &, then each bit in the "mask" that is zero is going to be zero in the result. Each bit that is 1 is going to have the value from the other operand.
So for example result = x & 0b11111111_11111111_11111111_11110111 (that big number is our mask and I'm showing it in binary) is going to have all the bits the same as x, except the fourth bit from the right, which is going to be 0, no matter if it's 0 or 1 in x.
So doing & with a "mask" is considered to be a "bit-reset" operation, or a "zeroing" operation.
For the | (or) operator, you can think of it as a "bit-set" operation. Every bit in the mask that is 1 is going to be 1 in the result. Every bit that is 0 is going to have whatever is in the other operand. So in the result, all the bits that were 1 in the mask are going to be set.
For example result = x | 0b1000 is going to have all the bits that were in x, except the fourth bit from the right, which is going to be 1 regardless of what it was in x.
Writing masks in binary is long and is a pretty recent thing in Java, so you are more likely to see masks written in hexadecimal. In this case 0xfffffff7 for the & example, and 0x8 for the | example.
Now let's look at your expression with a "mask" point of view:
dst<<1 means shifting dst by 1. All its bits are moved one position to the left, and the rightmost bit is set to zero. In essence, this is "making room" for something in the rightmost bit.
In the right parenthesis, the shift operator has precedence, so it is evaluated first. src is moved srcPos positions to the right. So the bit that was srcPos+1 places from the right is now the rightmost bit.
Now we "mask" that with 0x01. That is, 0b00000000_00000000_00000000_00000001. This is an & mask, so everything that is not the rightmost bit is going to be zero. Only the rightmost bit is saved. The end result is that it's the bit that used to be in the srcPos+1 place in src, and only that bit - all the rests are reset.
And now we "mask" this with the dst<<1 thing that we prepared. Since it is an | operation, it's a "setting" mask. Our mask only has one significant bit - the one that we didn't erase in the & operation. And it is on the rightmost position. If it's 1, it will be 1 in the result, and if it's 0, it will be 0 in the result (because the left operand has zero in that position).
So basically what it does is:
Push the bits in dst to the left.
Place the bit from the srcPos + 1 place from the right in the rightmost bit of it.
If the values in table are all unique positions between 0 and srcWidth, then this will give you a scrambling of the bits of src - in each round one bit will be pushed into dst based on the value of table[i].
" | " is Binary OR Operator which copies a bit if it exists in either operand.
as an example :
A|B
will give 61 which is 0011 1101.
" || " is called Logical OR Operator. If any of the two operands are non-zero, then the condition becomes true. as an example:
(A || B) is true.
| is bitwise OR not a logical OR
A bitwise OR operates on every bit in that long individually. This changes it's value, which is not the same as defining it.
Breaking down this line:
dst = (dst<<1) | (src>>srcPos & 0x01);
dst<<1 // means left shift 1 place. The same as multiply by 2. Zeros lowest bit.
src>>srcPos // means right shift srcPos places. The same as divide by 2 to the srcPos
// this puts the selected bit in the lowest place
& 0x01 // means set every bit to zero except the rightmost one which will stay the same
(src>>srcPos & 0x01) // means give me the value of the src bit at srcPos
(dst<<1) | (src>>srcPos & 0x01); // means shift dst left and put a src bit at the end
Here the bitwise OR works like it's appending a bit. That only works because the bits that won't be used have been carefully zero'ed on each side.
As the loop goes around table is controlling what bit to sample from src and whatever it picks is appended to the right end of dst. Thus table controls how src is permuted.
I am trying to understand the command "someByte << 2" in java. For what is it for? At the iscsi docmentation there is a caching mode page saying about DEMAND READ RETENTION PRIORITY and WRITE RETENTION PRIORIRY.
at the source there is this code for these messages:
// serialize byte 3
b = (byte)((demandReadRetentionPriority << 4) | writeRetentionPriority);
buffer.put(b);
Why do they use "<< 4" command with demandReadRetentionPriority and not with writeRetentionPriority? And what does << means in that case?
Thanks.
You can see from the documentation that the demandReadRetentionPriority is in the upper 4 bits (bits 7,6,5, and 4) of the byte and writeRetentionPriority is stored in the lower 4 bits (3,2,1, and 0) of the byte.
The code you provided is simply shifting the value stored in the demandReadRetentionPriority variable to the upper 4 bits. The << is a bit shift operation.
For example, if the value of demandReadRetentionPriority were 1 then it would be shifted 4 bits and the byte would have a binary representation as follows:
00010000
And in order for one of the lower bits of b to be set to 1, the corresponding bit in writeRetentionPolicy would have to also be set to 1, since the lower 4 bits of demandReadRetentionPolicy will be 0 after the bit shift.
<< is the "Signed left shift" operator, a bit shifting operator.
Example:
You have stored the number 279 that would be 100010111 in decimal. When you shift 4 steps to the left you get 1000101110000 (2224) because it will "move" the decimal number to the left and fill the spaces with zeroes.
100010111 << 4
=> 1000101110000
++++
Shifting operations are very fast because they are usually implemented in the hardware as a single machine instruction.
| is also an operator on the bit-level: The bitwise inclusive OR.
Summary of operators in java
I have an int 00000000000000000000000000001101 which represents 13 in base ten. I am trying to circular rotate the the bits by treating the 32 bit integer as a 4 bit integer because if I rotate the integer the value becomes very large. My desired answer after a right rotation of 2 for the above example would be 00000000000000000000000000000111 which is 7 in base 10.
Any help on doing this is greatly appreciated.
Try this:
x = (x >> 2) | ((x & 3) << 2);
This is just simulating the rotation via shifts and masks. I don't think there is anything better you could do, short of maybe making a lookup table (which may not actually be better); the CPU doesn't have opcodes for natively dealing with nybbles.
To rotate the lower 4 bits to the right by n, where n is 1, 2, or 3:
((x >> n) | (x << (4-n))) & 0xF;
The first part shifts the leftmost 4-n bits to the right; the second part shifts the rightmost n bits to the left. Then you or them together, and use & 0xF to zero extra bits that may have been set by the left shift.
I stumbled upon a question that asks whether you ever had to use bit shifting in real projects. I have used bit shifts quite extensively in many projects, however, I never had to use arithmetic bit shifting, i.e., bit shifting where the left operand could be negative and the sign bit should be shifted in instead of zeros. For example, in Java, you would do arithmetic bit shifting with the >> operator (while >>> would perform a logical shift). After thinking a lot, I came to the conclusion that I have never used the >> with a possibly negative left operand.
As stated in this answer arithmetic shifting is even implementation defined in C++, so – in contrast to Java – there is not even a standardized operator in C++ for performing arithmetic shifting. The answer also states an interesting problem with shifting negative numbers that I was not even aware of:
+63 >> 1 = +31 (integral part of quotient E1/2E2)
00111111 >> 1 = 00011111
-63 >> 1 = -32
11000001 >> 1 = 11100000
So -63>>1 yields -32 which is obvious when looking at the bits, but maybe not what most programmers would anticipate on first sight. Even more surprising (but again obvious when looking at the bits) is that -1>>1 is -1, not 0.
So, what are concrete use cases for arithmetic right shifting of possibly negative values?
Perhaps the best known is the branchless absolute value:
int m = x >> 31;
int abs = x + m ^ m;
Which uses an arithmetic shift to copy the signbit to all bits. Most uses of arithmetic shift that I've encountered were of that form. Of course an arithmetic shift is not required for this, you could replace all occurrences of x >> 31 (where x is an int) by -(x >>> 31).
The value 31 comes from the size of int in bits, which is 32 by definition in Java. So shifting right by 31 shifts out all bits except the signbit, which (since it's an arithmetic shift) is copied to those 31 bits, leaving a copy of the signbit in every position.
It has come in handy for me before, in the creation of masks that were then used in '&' or '|' operators when manipulating bit fields, either for bitwise data packing or bitwise graphics.
I don't have a handy code sample, but I do recall using that technique many years ago in black-and-white graphics to zoom in (by extending a bit, either 1 or 0). For a 3x zoom, '0' would become '000' and '1' would become '111' without having to know the initial value of the bit. The bit to be expanded would be placed in the high order position, then an arithmetic right shift would extend it, regardless of whether it was 0 or 1. A logical shift, either left or right, always brings in zeros to fill vacated bit positions. In this case the sign bit was the key to the solution.
Here's an example of a function that will find the least power of two greater than or equal to the input. There are other solutions to this problem that are probably faster, namly any hardware oriented solution or just a series of right shifts and ORs. This solution uses arithmetic shift to perform a binary search.
unsigned ClosestPowerOfTwo(unsigned num) {
int mask = 0xFFFF0000;
mask = (num & mask) ? (mask << 8) : (mask >> 8);
mask = (num & mask) ? (mask << 4) : (mask >> 4);
mask = (num & mask) ? (mask << 2) : (mask >> 2);
mask = (num & mask) ? (mask << 1) : (mask >> 1);
mask = (num & mask) ? mask : (mask >> 1);
return (num & mask) ? -mask : -(mask << 1);
}
Indeed logical right shift is much more commonly used. However there are many operations that require an arithmetic shift (or are solved much more elegantly with an arithmetic shift)
Sign extension:
Most of the time you only deal with the available types in C and the compiler will automatically sign extend when casting/promoting a narrower type to a wider one (like short to int) so you may not notice it, but under the hood a left-then-right shift is used if the architecture doesn't have an instruction for sign extension. For "odd" number of bits you'll have to do the sign extension manually so this would be much more common. For example if a 10-bit pixel or ADC value is read into the top bits of a 16-bit register: value >> 6 will move the bits to the lower 10 bit positions and sign extend to preserve the value. If they're read into the low 10 bits with the top 6 bits being zero you'll use value << 6 >> 6 to sign extend the value to work with it
You also need signed extension when working with signed bit fields
struct bitfield {
int x: 15;
int y: 12;
int z: 5;
};
int f(bitfield b) {
return (b.x/8 + b.y/5) * b.z;
}
Demo on Godbolt. The shifts are generated by the compiler but usually you don't use bitfields (as they're not portable) and operate on raw integer values instead so you'll need to do arithmetic shifts yourself to extract the fields
Another example: sign-extend a pointer to make a canonical address in x86-64. This is used to store additional data in the pointer: char* pointer = (char*)((intptr_t)address << 16 >> 16). You can think of this as a 48-bit bitfield at the bottom
V8 engine's SMI optimization stores the value in the top 31 bits so it needs a right shift to restore the signed integer
Round signed division properly when converting to a multiplication, for example x/12 will be optimized to x*43691 >> 19 with some additional rounding. Of course you'll never do this in normal scalar code because the compiler already does this for you but sometimes you may need to vectorize the code or make some related libraries then you'll need to calculate the rounding yourself with arithmetic shift. You can see how compilers round the division results in the output assembly for bitfield above
Saturated shift or shifts larger than bit width, i.e. the value becomes zero when the shift count >= bit width
uint32_t lsh_saturated(uint32_t x, int32_t n) // returns 0 if n == 32
{
return (x << (n & 0x1F)) & ((n-32) >> 5);
}
uint32_t lsh(uint32_t x, int32_t n) // returns 0 if n >= 32
{
return (x << (n & 0x1F)) & ((n-32) >> 31);
}
Bit mask, useful in various cases like branchless selection (i.e. muxer). You can see lots of ways to conditionally do something on the famous bithacks page. Most of them are done by generating a mask of all ones or all zeros. The mask is usually calculated by propagating the sign bit of a subtraction like this (x - y) >> 31 (for 32-bit ints). Of course it can be changed to -(unsigned(x - y) >> 31) but that requires 2's complement and needs more operations. Here's the way to get the min and max of two integers without branching:
min = y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1)));
max = x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1)));
Another example is m = m & -((signed)(m - d) >> s); in Compute modulus division by (1 << s) - 1 in parallel without a division operator
I am not too sure what you mean. BUt i'm going to speculate that you want to use the bit shift as an arithmetic function.
One interesting thing i have seen is this property of binary numbers.
int n = 4;
int k = 1;
n = n << k; // is the same as n = n * 2^k
//now n = (4 * 2) i.e. 8
n = n >> k; // is the same as n = n / 2^k
//now n = (8 / 2) i.e. 4
hope that helps.
But yes you want to be careful of negative numbers
i would mask and then turn it back accordingly
In C when writing device drivers, bit shift operators are used extensively since bits are used as switches that need to be turned on and off. Bit shift allow one to easily and correctly target the right switch.
Many hashing and cryptographic functions make use of bit shift. Take a look at Mercenne Twister.
Lastly, it is sometimes useful to use bitfields to contain state information. Bit manipulation functions including bit shift are useful for these things.
This code segment:
(x >>> 3) & ((1 << 5) - 1)
apparently results in a 5-bit integer with bits 3 - 7 of x.
How would you go about understanding this?
Let's look at ((1 << 5) - 1) first.
1 << 5 is equal to 100000 in binary.
When we subtract 1, we're left with 11111, a binary number of five 1s.
Now, it's important to understand that a & 0b11111 is an operation that keeps only the 5 least significant bits of a. Recall that the & of two bits is 1 if and only if both of the bits are 1. Any bits in a above the 5th bit, therefore, will become 0, since bit & 0 == 0. Moreover, all of the bits from bit 1 to bit 5 will retain their original value, since bit & 1 == bit (0 & 1 == 0 and 1 & 1 == 1).
Now, because we shift the bits of x in x >>> 3 down by 3, losing the three least significant bits of x, we are applying the process above to bits 4 to 8 (starting at index 1). Hence, the result of the operation retains only those bits (if we say the first bit is bit 0, then that would indeed be bit 3 to bit 7, as you've stated).
Let's take an example: 1234. In binary, that's 10011010010. So, we start with the shift by 3:
10011010010 >>> 3 = 10011010
Essentially we just trim off the last 3 bits. Now we can perform the & operation:
10011010
& 00011111
--------
00011010
So, our final result is 11010. As you can see, the result is as expected:
bits | 1 0 0 1 1 0 1 0 0 1 0
index | 10 9 8 7 6 5 4 3 2 1 0
^-------^
(x >>> 3)
Shifts x right 3 bits logically, i.e. not sign-extending at the left. The lower-order 3 bits are lost. (This is equivalent to an unsigned division by 8.)
1 << 5
Shifts 1 left 5 bits, i.e. multiplies it by 32, yielding 0b00000000000000000000000000100000.
-1
Subtracts one from that, giving 31, or 0b00000000000000000000000000011111.
&
ANDs these together, yielding only the lower-order 5 bits of the result of x >>> 3, in other words bits 3..7 of the original x.
"How would you go about understanding this?".
I assume that you are actually asking how you should go about understanding it. (As distinct from someone just explaining it to you ...)
The way to understand it is to "hand execute" it.
Get a piece of paper and a pencil.
Based on your understanding of how Java operator precedence works, figure out the order in which the operations will be performed.
Based on your understanding of each operator, write the input patterns of bits on the piece of paper and "hand execute" each operation ... in the correct order.
If you do this a few times with a few values of x, you should get to understand why this expression gives you a 5 bit number.
If you repeat this exercise for a few other examples, you should get to the point where you don't need to go through the tedious process of working it out with a pencil and paper.
I see that #arshajii has essentially done this for you for this example. But I think you will get a deeper understanding if you do / repeat the work for yourself.
One thing to remember about integer and bitwise operations in Java is that the operations are always performed using 32 or 64 bit operations ... even if the operands are 8 or 16 bit. Another thing to remember (though it is not relevant here) is that the right hand operand of a shift operator is chopped to 5 or 6 bits, depending on whether this is a 32 or 64 bit operation.