I have a very simple question: I want to know what is the meaning of this java operation. I'm a beginner in java and can't understand what it does. I know that it is a packed int storing a color
(alpha << 24) | (red << 16) | (green << 8) | blue
Another question: I want to go from a 0xFFFFFFFF value to a RGB type color, how can I separate this packed int into RGB channels?
Regarding the first question:
The expressison is loading four 8-bit quantities into a 32-bit int. Although generally this kind of boolean manipulation is done with unsigned ints to avoid complications I won't go into here.
The line you're showing is shifting the alpha component's value (e.g. its 8-bits) 24 bits to the left, to create a result which has alpha occupying the high-order byte of a 4-byte (32-bit) integer.
Then it shifting the red component 16 bits to the left (increasing its numeric value binary orders of magnitude), and logically ORing the result of that shift operation into the 32-bit integer that alpha was stored in, merging in the value, to occupy the 3rd byte. The result at that point will be that the top two bytes will have the alpha and red values, and so on.
Regarding the second question:
You can invert the procedure and use boolean operators:
unsigned int v = 0xff557788;
int blue = v & 0xff;
int green = v >> 8 & 0xff;
int red = v >> 16 & 0xff;
int alpha = v >> 24 & 0xff;
In this example we're shifting the field right in multiples of 8 to get the different bytes into the lowest byte, and then masking (e.g. logically ANDing with) 0xff to get a value that excludes the high order 3 bytes.
Related
I have to decode an image by negating the upper 4 bits of each pixel. How can I do this using bitwise operations?
You can apply bitwise operations on data, not pixels. So the answer to your question depends on how pixels are encoded in your application.
Having said that, to negate (assuming you mean "toggle") the leftmost four bits of a byte you should apply a bitwise XOR with the mask 11110000:
b ^= 0b11110000;
Assuming 32-bit ints:
x = (~x & 0xFF000000) | (x & 0x00FFFFFF)
public int getRGB(Object inData) {
return (getAlpha(inData) << 24)
| (getRed(inData) << 16)
| (getGreen(inData) << 8)
| (getBlue(inData) << 0);
}
So, what does this return statement actually do? Four ints are shifted, but what is returned?
It returns an int whose first (MSB) byte is the Alpha value, its 2nd byte is the Red value, its 3rd byte is the Green value and its last byte is the Blue value.
highest lowest
bit bit
|--------|--------|--------|--------|
Alpha Red Green Blue
(8 bits) (8 bits) (8 bits) (8 bits)
What you get is the following :
Alpha | Red | Green | Blue - an 32 bit ARGB value - 8 bits for each. As you can see, alpha is shifted 24 bits to the left (leftmost - most significant bits), after which comes the red, with 8 bits, thus placing red in second first 8 bits and masking the remaining 16. Afterward, green is shifted with 8 bits, masking the last byte and finally, blue is put in its place.
| is bitwise OR with strict evaluation, in contrast to ||, which may stop evaluation of the statements in the condition as soon as one expression returns true. But these methods (presumably) return integers, so in Java you (to my knowledge) cannot test these against true directly anyway. No problem since that is not what you are doing - you are shifting the individual results from the methods, filling up new bits with 0 and cutting off the old ones. What this achieves is to pack the (presumably) at most byte-sized, positive values (0 to 255) in one of the 4 bytes which make up an integer. Essentially this is packing 4 pieces of information which require one byte each into one variable of type integer. The type of the target variable could be anything, as long as it has enough bytes to store the information, but it gets more sloppy and questionable from there.
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.
I am working on a small project. During the searching on google I see some code in java .
int red = (pixel >> 16) & 0x000000FF;
But I do not understand what is the meaning of that ? CAn anybody explain summary of that logical operation ? I read that it is shifted sth like that but shift of what ?
The red component of a color is stored as a number between 0-255, but "packed" into an integer. Here's my ASCII art, in binary, 32 bits per integer, showing the 8 bits each for Alpha,Red,Green,and Blue. Read the bit number vertically! I'm numbering from 1, not 0. (Also, you can argue that the numbers go the wrong direction - they are there just to help you count!)
11111111112222222222333
12345678901234567890123456789012
AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB the pixel value
The pixel >> 16 will shift the result right by 16 bits. In effect, this removes the G and B stuff
AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB move everything 16 to the right, this becomes
----------------AAAAAAAARRRRRRRR
where the - depends on sign. You can look it up but in this case it doesn't matter.
So, you have your Red number, almost. There is still the Alpha component, all that AA.... If you mask ("and") with 0xFF, which is the lowest 8 bits
----------------AAAAAAAARRRRRRRR (result of the bit shift)
00000000000000000000000011111111 (0xFF)
you get
000000000000000000000000RRRRRRRR
which is the result desired, a number between 0 and 255.
This is a bitwise "AND" operator. When it is applied to the number FF (hex) it clears all bits of an int except the final 8.
Recall that bitwise "AND" goes through a binary representation of a number, and puts ones in the result only in positions where both operands have ones. Since a 32-bit mask containing FF looks like this in binary
00000000000000000000000011111111
the upper three bytes of the result are going to be zeros. The last byte, where FF has all ones, will be equal to the last byte of the first operand.
& - bitwise AND operator
>> - right shift operator - shifts a bit pattern to the right
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
For example
4 in binary 100, if you do >>1 that would be 010 which is 2
8 in binary 1000, if you do >>1 that would be 0100 which is 4
See also
What are bitwise shift (bit-shift) operators and how do they work?
I can't find out what << means in Java because I can't search for it on Google - I am absolutely lost!
The code in question is:
public int getRGB() {
return ((red << 16) | (green << 8) | blue);
}
It's taken from: http://java.sun.com/docs/books/tutorial/essential/concurrency/example/ImmutableRGB.java
I would really appreciate someone telling me, thanks!
Left shift of the bits
If red == 4 (which in binary is: 00000100) then red << 16 will insert sixteen 0-bits at its right, yielding: 000001000000000000000000 which is 262144 in decimal
Q. What is this?
A. An "operator"
Q. How do I get to know about operators in java?
A. Google for "Java operators"
And the result is this:
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 shift a number of bits. It is equivalent to multiplying by two that many times.
It's used for setting specific bits in a byte, or specific bytes in a word.
It is the left shift operator. Here's some more information on shift operators from the Java Tutorial.
In your example code the three integer values: red, green and blue will typically have values 0-255. Hence, it is possible to combine these values and represent them as a single integer by shifting the red value by 16 bits, shifting the green value by 8 bits and then performing a bitwise-OR operation to combine the values.
its a bit shift. search for operators java, it will return you detailed explanations.
"<<" means left shift the bits of a value.
">>" means right shift the bits of a value.
example:
int a = 5; //the binary value of 5 is 101
a = a << 3; //left shift 3 bits on 101, 101 000<< add 3 bits(0) on the right, become '101000'
System.out.println(a); //this will display 40, the decimal for '101000'
int b = 9; //the binary value of 8 is 1001
b = b >> 3; //right shift 3 bits on >>000 1001 add 3 bits(0) on the left, truncate the last 3 bits on the right become '001'
System.out.println(b); //this will display 1, the decimal for '001'
Its a left bit shift
Its left shifting and convert Red, Green, Blue into 24 bit Number