This question already has answers here:
What are bitwise shift (bit-shift) operators and how do they work?
(10 answers)
Closed 6 years ago.
Hey I am working with image in JAVA (sobel operator) and I don't understand what some lines of code mean.
int p = img.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
p = (a<<24) | (avg<<16) | (avg<<8) |avg;
So could someone explain what these lines mean?
(p>>24)&0xff
p = (a<<24) | (avg<<16) | (avg<<8) |avg;
Those are bitwise operations. p>>24 shifts first byte in p int 24 places to the right and &0xff performs bitwise and with shifted number and hexadecimal number ff(decimal 255). avg << 16 shifts first byte in avg int 16places to the left. And | performs bitwise or with other values. These are so called bitmasks. Search terms bitwise operations and bitmasks for more information. Hope i helped :)
Related
This question already has answers here:
What does >> do in Java?
(4 answers)
Closed 5 years ago.
Can someone explain the following code snippet, please?
methodAttributeLength = (long)dis.readUnsignedShort() << 16 | dis.readUnsignedShort();
I checked this in java doc .But I can't get the idea. I know what the java.io.DataInputStream.readUnsignedShort() method does.But the problem is that <<16 thing.
DataInputStream#readUnsignedShort return a int which spend 32 bits, but the short type spend 16 bits.
int << 16 will shift the low 16 bits to high 16 bits and fills 0 in the low 16 bits. for example:
int value = 0b11111111000000001000000011111111;
^---------------
int high = 0b10000000111111110000000000000000;
// high == value << 16
in this case, and the | operator is joins high bits and low bits together. for example:
int high = 0b10000000111111110000000000000000;
int low = 0b00000000000000001000000000000001;
int value = 0b10000000111111111000000000000001;
// value == high | low;
on the other hand, your protocol saving an int into two shorts which are a high short and a low short. and the code above is read the int value from two shorts.
for more details you can see bitewise operators and shift operators.
I have cracked my head enough and hence asking here:
This works:
int dummy_1, dummy_2;
long final_dummy;
dummy_1 = 0x12345678;
dummy_2 = 0x78563412;
final_dummy = (long)dummy_1 | (long)dummy_2<<32;
System.out.println(String.format("%08X", final_dummy));
Answer : 7856341212345678
This doesnt work:
int dummy_1, dummy_2;
long final_dummy;
dummy_1 = 0xB6F93000;
dummy_2 = 0xB6F93000;
final_dummy = (long)dummy_1 | (long)dummy_2<<32;
System.out.println(String.format("%08X", final_dummy));
Answer: FFFFFFFFB6F93000
Expected answer : B6F93000B6F93000
0xB6F93000 is actually the int value -1225183232. When coerced to long, it becomes 0xFFFFFFFFB6F93000L, which is also -1225183232.
When you convert int to long you need to make it an unsigned conversion.
// In Java 8
int dummy_1 = 0xB6F93000;
int dummy_2 = 0xB6F93000;
long final_dummy = Integer.toUnsignedLong(dummy_1) | Integer.toUnsignedLong(dummy_2) << 32;
// In all Java versions
int dummy_1 = 0xB6F93000;
int dummy_2 = 0xB6F93000;
long final_dummy = (dummy_1 & 0xFFFFFFFFL) | (long)dummy_2 << 32;
In the code that doesn't work, your initial dummy_1 and dummy_2 values are negative; in Java, all numeric types are signed. The highest bit is set, which is seen because the first hex digit is greater than or equal to 8.
Because these values are negative, when casted to a long, sign extension occurs.
0xB6F93000 => 0xFFFFFFFFB6F9000L
When logically ORed, those F digits remain, explaining why the most significant 8 hex digits (4 bytes) are Fs instead of your value.
Use a mask to clear those sign-extended bits prior to ORing them.
final_dummy = (((long) dummy_1) & 0xFFFFFFFFL) | (((long)dummy_2) & 0xFFFFFFFFL) << 32;
This will clear the most significant 8 hex digits, as if sign extension did not take place. With this change, I get:
B6F93000B6F93000
Bit-anding on dummy_2 is not necessary, because the shift eliminates those 32 bits anyway.
final_dummy = (((long) dummy_1) & 0xFFFFFFFFL) | (long) dummy_2 << 32;
As an aside, normal Java naming conventions dictate that the variables names should be dummy1, dummy2, and finalDummy.
This question already has answers here:
why is 1>>32 == 1?
(2 answers)
Closed 8 years ago.
I found this integer variable declaration in a Java class:
int i7 = ((0x1F & arrayOfByte[i][4]) << 9) + ((0xFF & arrayOfByte[i][5]) << 1) + (0x1 & (0xFF & arrayOfByte[i][6]) >>> 7);
But are the arrows (>>> and <<) mean/doing?
Kind regards,
Bastiaan
UPDATE:
Sow they are bitshift operators, thanks!
Found this good explanation video: https://www.youtube.com/watch?v=1qa0zvcdHXI
Throughout this post let's assume numbers are one hex digit, just for simplicity.
">>" is the bit shift operator. For example:
8 >> 1 == 8 / 2 == 4;
Which in binary is equivalent to
b1000 >> 1 == b0100;
Adding the third ">" into the operator inserts a 0 into the now far left slot, instead of doing sign extension to determine it's value.
-1 >> 1 = b1111
-1 >>> 1 = b0111
This is more useful for things like bit masks, where forcing the new value to 0 is convenient. And is only applicable to right shifting, there is no <<< operator.
|=
I'm curious to learn about this operator,
I've seen this notation used while setting flags in Java.
for example:
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Does it perform some kind of bit manipulation?
What does this mark exactly do?
Are there any other well known signs similar to this?
It is equivalent to
notification.flags = notification.flags | Notification.FLAG_AUTO_CANCEL;
where | is bitwise OR operator which OR the two variables bit-by-bit.
It is well known by itself. There are also +=, -=, *=, /=, %=, &=, ^=.
This syntax is also available in C/C++ and other languages. It is a bitwise OR and the same as:
notification.flags = notification.flags | Notification.FLAG_AUTO_CANCEL;
and similar to other operators like addition, subtraction, etc. For example:
i += 5;
is the same as:
i = i + 5;
(1) Does it perform some kind of bit manipulation?
If you use | with numeric operands then yes, it will be bitwise OR, if you use it on boolean operands it will be logical (non-short-circuit) OR. Example
Logical OR: lets say that 1 represents true and 0 false
+---+---+-------+
| p | q | (p|q) |
+---+---+-------+
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
+---+---+-------+
Bitwise OR will perform similar operation as boolean but will use corresponding bits
decimal binary
6 = 00110
3 = 00011
OR -------------
00111
(2) What does this mark exactly do?
x |= y is the same as x = x | y so it will calculate x | y and store it in x.
(3) Are there any other well known signs similar to this?
Yes, every arithmetic, bitwise or bit shift operator can be used this way: += -= *= /= %= &= ^= |= <<= >>= >>>=
Here are some additional informations about usage of |= in
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Lets say that we have five properties.
Property1
Property2
Property3
Property4
Property5
We can use last five bits of number to represents situations where we have (1) or don't have (0) some property.
...00xxxxx
│││││
││││└─ flag for Property1
│││└── flag for Property2
││└─── flag for Property3
│└──── flag for Property4
└───── flag for Property5
Now, lets say that we want to use only properties 1, 2 and 4. To do this we have to set bits indexed with 0, 1 and 3 to value 1 like
...0001101
│││││
││││└─ (1) has Property1
│││└── (0) no Property2
││└─── (1) has Property3
│└──── (1) has Property4
└───── (0) no Property5
In other words we have to produce number 13 (= **1***8 + **1***4 + **0***2 + **1***1). We can do this with | OR bitwise operator 8|4|1 because
8 = ...001000
4 = ...000100
1 = ...000001
OR -------------
13 = ...001101
But to avoid magic numbers we can create constants that will represents our properties in bit world. So we can create
public class MyProperties {
//...
public static final int PROPERTY_1 = 0b0000_0001; // = 1
public static final int PROPERTY_2 = 0b0000_0010; // = 2
public static final int PROPERTY_3 = 0b0000_0100; // = 4
public static final int PROPERTY_4 = 0b0000_1000; // = 8
public static final int PROPERTY_5 = 0b0001_0000; // = 16
//...
//rest of code: methods, constructors, other fields
}
and use it later like
int context = Properties.PROPERTY_1|Properties.PROPERTY_2|Properties.PROPERTY_4
which is more readable than int context = 8|4|1.
Now if we want to change our context and lets say add PROPERTY_3 we can use
context = context | Properties.PROPERTY_3;
or shorter version based on compound assignments operators
context |= Properties.PROPERTY_3;
which will do this calculations
context = 000...00001101
PROPERTY_3 = 000...00000010
OR ------------------------
000...00001111
(main difference between adding value of PROPERTY_3 to context and using bitwise OR | is that when context will already have PROPERTY_3 set to 1 then OR will no effect it).
Now if you take a look here idea of using single bits as flags for properties was used in Notification class, where FLAG_AUTO_CANCEL constant has value 16 (0x010 in hexadecimal, 0b0001_0000 in binary).
Does it perform some kind of bit manipulation?
Yes. It "OR"s the right-hand-side operand into the left-hand-side one.
What does this mark exactly do?
It's an assignment coupled with an OR.
Are there any other well known signs such as this?
There are plenty: +=, -=, *=, /=, %=, &=, and so on. Collectively, they are called compound assignment operators. They are described in section 15.26.2 of the Java Language Specification.
It is called bitwise or operator. For example,
5 = 0000 0101
2 = 0000 0010
5 | 2 = 0000 0111
= 14
So, this concept is used when a same option can use multiple values.
As an example, consider a variable flags equal to one.
int flags = 1;
Now, if a flag value of 4 is added to it with bitwise or,
flags |= 4; // 0
You can determine whether 4 was applied on flags with the bitwise and.
if (flags & 4 == 4) // returns true
If that flag has been applied on the flags, bitwise and returns flag. In this way we can use bitwise and & bitwise or.
Hope this helps.
All,
I have been practicing coding problems online. Currently I am working on a problem statement Problems where we need to convert Big Endian <-> little endian. But I am not able to jot down the steps considering the example given as:
123456789 converts to 365779719
The logic I am considering is :
1 > Get the integer value (Since I am on Windows x86, the input is Little endian)
2 > Generate the hex representation of the same.
3 > Reverse the representation and generate the big endian integer value
But I am obviously missing something here.
Can anyone please guide me. I am coding in Java 1.5
Since a great part of writing software is about reusing existing solutions, the first thing should always be a look into the documentation for your language/library.
reverse = Integer.reverseBytes(x);
I don't know how efficient this function is, but for toggling lots of numbers, a ByteBuffer should offer decent performance.
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
...
int[] myArray = aFountOfIntegers();
ByteBuffer buffer = ByteBuffer.allocate(myArray.length*Integer.BYTES);
buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int x:myArray) buffer.putInt(x);
buffer.order(ByteOrder.BIG_ENDIAN);
buffer.rewind();
int i=0;
for (int x:myArray) myArray[i++] = buffer.getInt(x);
As eversor pointed out in the comments, ByteBuffer.putInt() is an optional method, and may not be available on all Java implementations.
The DIY Approach
Stacker's answer is pretty neat, but it is possible to improve upon it.
reversed = (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
We can get rid of the parentheses by adapting the bitmasks. E. g., (a & 0xFF)<<8 is equivalent to a<<8 & 0xFF00. The rightmost parentheses were not necessary anyway.
reversed = i<<24 & 0xff000000 | i<<8 & 0xff0000 | i>>8 & 0xff00 | i>>24 & 0xff;
Since the left shift shifts in zero bits, the first mask is redundant. We can get rid of the rightmost mask by using the logical shift operator, which shifts in only zero bits.
reversed = i<<24 | i>>8 & 0xff00 | i<<8 & 0xff0000 | i>>>24;
Operator precedence here, the gritty details on shift operators are in the Java Language Specification
Check this out
int little2big(int i) {
return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}
The thing you need to realize is that endian swaps deal with the bytes that represent the integer. So the 4 byte number 27 looks like 0x0000001B. To convert that number, it needs to go to 0x1B000000... With your example, the hex representation of 123456789 is 0x075BCD15 which needs to go to 0x15CD5B07 or in decimal form 365779719.
The function Stacker posted is moving those bytes around by bit shifting them; more specifically, the statement i&0xff takes the lowest byte from i, the << 24 then moves it up 24 bits, so from positions 1-8 to 25-32. So on through each part of the expression.
For example code, take a look at this utility.
Java primitive wrapper classes support byte reversing since 1.5 using reverseBytes method.
Short.reverseBytes(short i)
Integer.reverseBytes(int i)
Long.reverseBytes(long i)
Just a contribution for those who are looking for this answer in 2018.
I think this can also help:
int littleToBig(int i)
{
int b0,b1,b2,b3;
b0 = (i&0x000000ff)>>0;
b1 = (i&0x0000ff00)>>8;
b2 = (i&0x00ff0000)>>16;
b3 = (i&0xff000000)>>24;
return ((b0<<24)|(b1<<16)|(b2<<8)|(b3<<0));
}
Just use the static function (reverseBytes(int i)) in java which is under Integer Wrapper class
Integer i=Integer.reverseBytes(123456789);
System.out.println(i);
output:
365779719
the following method reverses the order of bits in a byte value:
public static byte reverseBitOrder(byte b) {
int converted = 0x00;
converted ^= (b & 0b1000_0000) >> 7;
converted ^= (b & 0b0100_0000) >> 5;
converted ^= (b & 0b0010_0000) >> 3;
converted ^= (b & 0b0001_0000) >> 1;
converted ^= (b & 0b0000_1000) << 1;
converted ^= (b & 0b0000_0100) << 3;
converted ^= (b & 0b0000_0010) << 5;
converted ^= (b & 0b0000_0001) << 7;
return (byte) (converted & 0xFF);
}