Shifting bit values [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have recently started learning java of my own back and I am having trouble with one part in particular. Today I read up on shifting bit values and I was wondering if what I am doing is correct?
I want to shift a value to the right by 16 bits and then clear the upper 24 bits by anding the value with an 8-bit mask of ones. Here is a segment of my code:
int shift(){
point = point >> 16; //shifts the value to the right by 16 bits
point = point & 0xFF; //clear the upper 24 bits
return point;
}
Is this correct? Am I using this technique correctly?
Thanks!

Yes.
some content to fill out the 30 characters minimum length
OK, looks like that joke is not well-received, I was anticipating people to like this satyrical answer. Oh well, apparently people in SO are more serious than I thought.
Well, like others have mentioned, you can actually check it yourself!
As you have written in your code comments, you are already doing it right to convert your comment (human understanding) into code (machine understanding).
How do I know that you're correct? Well, you can check the online resources:
For bit manipulation
Or just this Wikipedia entry
So far your code seems to match your intention, after consulting those resources.
But, you say, that's theoretical, how do I know empirically that my answer is correct?
Well, you can do this method:
Build some sample test cases.
For this case you can use hexadecimal number so that you can easily confirm it (because you can see each bit).
For example: try 0xFFFFFFFF, 0x80000000, 0xC0C0C0C0.
Find the correct answer manually.
In this case, try shifting the bit yourself (using pen and paper)
For 0xFFFFFFFF, which is a 32-bit number with all 1's, when you shift 16 bits to the right you will get 0x0000FFFF, which is a 32-bit number with 1's only at the last 16 bits.
Then you do and AND operation with 0xFF, which is a 32-bit number with 1's only at the last 8 bits. This will again give you 0xFF, since only at the last 8 bits both numbers have bit 1.
Repeat for other examples. You should get 0x00 and 0xC0 for the other example.
Run your code on those input.
To run your code, you can use something called Java compiler (it's usually called javac in most systems).
If you really are a beginner, you can try online compiler like this
Just put your code there and run (with Input/Output (I/O) management, explained here)
Compare your output with the program output.
Usually, this alone will give you confidence that your code is correct.
But sometimes there are tricky cases which make the code incorrect even though it's correct for some small examples. Fortunately we already checked the logic using theoretical answer above.
So I hope that helps!

First let me welcome you to Java. Good choice!
About your question: If this is correct or not depends on what you expect.
But first of all, when learning Java you should do two things:
Get a development environment like Eclipse.
Learn how to write litte test routines with Junit. Here's a JUnit Tutorial
I've taken your code and embedded it in a test routine to see what actually happens:
public class Stackoverflow extends TestCase {
#Test
public final void test() throws IOException {
testNprint(1234);
testNprint(-1234);
testNprint(0);
testNprint(255);
testNprint(256);
testNprint(Integer.MAX_VALUE);
testNprint(Integer.MIN_VALUE);
}
private void testNprint(int point) {
System.out.printf("int: %1$d (0x%1$X) -> shifted: %2$d (0x%2$X)\n",
point, shift(point));
}
private int shift(int point) {
point = point >> 16; //shifts the value to the right by 16 bits
point = point & 0xFF; //clear the upper 24 bits
return point;
}
}
And here's the result. Now you can answer your question: Are the numbers as expected?
int: 1234 (0x4D2) -> shifted: 0 (0x0)
int: -1234 (0xFFFFFB2E) -> shifted: 255 (0xFF)
int: 0 (0x0) -> shifted: 0 (0x0)
int: 255 (0xFF) -> shifted: 0 (0x0)
int: 256 (0x100) -> shifted: 0 (0x0)
int: 2147483647 (0x7FFFFFFF) -> shifted: 255 (0xFF)
int: -2147483648 (0x80000000) -> shifted: 0 (0x0)
BTW: I guess the result is not as you've expected it :-) For the reason find out about the difference of >> and >>>.

Related

java : shift distance for int restricted to 31 bits

Any idea why shift distance for int in java is restricted to 31 bits (5 lower bits of the right hand operand)?
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19
x >>> n
I could see a similar question java Bit operations >>> shift but nobody pointed the right answer
The shift distance is restricted to 31 bits because a Java int has 32 bits. Shifting an int number by more than 32 bits would produce the same value (either 0 or 0xFFFFFFFF, depending on the initial value and the shift operation you use).
It's a design decision, but it seems a bit unfortunate at least for some use cases. First some terminology: let's call the approach of defining as zero all shifts amounts larger than the number of bits in the shifted word the saturating approach, and the Java approach of using only the bottom 5 (or 6 for long) bits to define the shift amount as the mod approach.
You can look at the problem by listing the useful shift values. Those are shift amounts that result in unique output values1. If you take >>>, the interesting values are 0 though 32 inclusive. 0 results in an unchanged value, and 32 results in 0. Shifting by more than 32 would again produce the same result as 32, sure - but java doesn't even let you shift by 32: it stops at 31! A shift by 32 will, perhaps unexpectedly, leave your value unchanged.
In many uses of >>> a shift by 32 is not possible, or the Java behavior works. In other cases, however, the natural result is 32, and you must special case zero.
As to why they would choose that design? Well, it probably helped that the common PC hardware at the time (x86, just like today) implements shifts in exactly that way (using only the last 5 bits for 32-bit shifts, and the last 6 for 64-bits). So the shifts can be directly mapped to hardware without any special cases, conditional moves or branches2.
Furthermore, for hardware that doesn't implement those semantics by default, it is easy to get the Java semantics by a simple mask: shiftAmount & 0x1F. That's going to be fast on all hardware. The reverse mapping - implementing saturating shifts on hardware that doesn't support it is more complex: you may need a costly compare and branch, some bit twiddling hacks or predicated moves to handle the > 31 case.
Finally, the mod approach is quite natural for many algorithms. For example, if you are implementing a bitmap structure, addressable per-bit, a good implementation may be to have an array of integers, with each integer representing 32 bits. Internally to index into the Nth bit, you would break N down into two parts - the high 27 bits would find the word in the array the bit is in, and the low 5 bits would pick the bit out of the word. To pick the bit out of the word (e.g., to move it to the LSB), you might do:
int val = (word >>> (index & 0x1F)) & 1
That sets val to 1 if the bit was set, 0 otherwise. However, because of the way the Java >>> operator was specified, you don't need the & 0x1F part at all, because it is already implied in the mod definition! So you can omit it, and indeed the JDK's BitSet uses exactly that trick.
1 Granted, any value without a 1 in the MSB may not produce unique values under >>>, once all the 1s get shifted off, so let's just talk about any value with a leading one.
2 For what it's worth, I checked ARM and the semantics are even weirder: for variable shifts, the bottom eight bits of the shift amount is used. So the shift is a weird hybrid - it is effectively a saturating shift once you exceed 31, but only up to 255, at which point it loops around and suddenly has non-zero values for the next 31 values, etc.

Alternative for checking module before using `>>`?

In- Java , C# , Javascript :
AFAIU - the >> is a shift right operand which can deal also with signed numbers :
There is no problem with :
12>>2 --> 3
And also for signed number :
-12>>2 --> -3
But when the decimal result is not an integer , the result are differnt:
10>>2 --> 2
Whereas -10>>2 --> -3
I'm fully aware why it is happening (via Two's complement ) , but :
Question :
Does it mean that when I use the fastest division ever >> - I must check that :
10%4 is not zero ?
Am I missing something here ?
You can use methods like Integer.numberOfTrailingZeros() and Long.numberOfTrailingZeros() to tell if shifting will be accurate or truncated.
You can also use bitwise AND to test the last bits, for example testing the last 4 bits:
int i = 543;
if ((i & 0x0f) == i )
System.out.println("Last 4 bits are zeros!");
Although note that it's not worth using bit shift for "fast" division. You're not going to outsmart the compiler because most of today's compilers are intelligent enough to optimize these cases.
More on this: Is multiplication and division using shift operators in C actually faster?
Edit:
The answer to your question is that bit shifting is not defined as "the fastest division ever", it is defined as what its name says: bit shifting, which in case of negative numbers gives (or might give) different result.
You're not missing anything. If your input can be negative, your 2 options are:
Either check the value and if it might give different result, corrigate it or use division. A simple check might be to test if it's negative, or test the last bits (described above).
Completely avoid using bit shift for division purposes.

Valid way to move bits in java

I'm working on an assignment for school and I'm getting strange output. So, I figured I should start checking some of my more basic methods before I get to the fancier ones. The question I have is this:
would the method
public static short get16(byte a, byte b){
return (short)(a*Math.pow(2,8)+b)
}
return a short where the first 8 bits are byte a and the last 8 bits are byte b?
I don't see why it wouldn't, since multiplying by 2^8 would be the same as left shifting 8 bits to the left. And adding the second byte would make up for the 8 0's achieved by multiplying by 2^8. Is this correct?
I wouldn't recommend using Math.pow to compute 256. pow is notoriously hard to implement correctly; some extant implementations don't even get the exact cases right!
Also, bytes in Java are signed, so you probably want to say (a&255) and (b&255) rather than just a and b. Sign extension will ruin everything for you.
Some things you should know:
"Math.pow" is a floating-point function. Don't do integer calculation by calling floating-point functions and then rounding the result.
Java virtual machine is internally a 32-bit system. All "byte" and "short" mathematical expressions are internally evaluated as "int". Even an addition of two bytes goes internallly like this: 1) convert the bytes to ints, 2) add the ints, 3) convert the lower 8 bits to byte.
The correct way is:
return (short) ((a << 8) + (b & 255));
or
return (short) ((a << 8) | (b & 255));
When "byte" is converted to "int", the sign bit gets copied into the new bits. For example 0b01010101 becomes 0b00000000_00000000_00000000_01010101, because the first bit was 0, but 0b10101010 becomes 0b11111111_11111111_11111111_10101010.

Java bitmask range

I need to extract an exact range of bits from an existing long, specifically I need bits 51:12 from a 64 bit value.
The value is:
0x0000000415B2C01E
So the value of bits 51:12 should be:
0x0000415B2C
I'm a bit confused as to how to actually extract that range, or any range for that matter. I've been told to simply left shift by 12 (value << 12) to obtain the bits I need, but that gives me the value of:
0x415B2C01E000
Now I might be completely misunderstanding how bit shifting works, but I can't get my head around how to extract bit ranges. I've found a lot of existing stuff on it, but I'm even more confused about it all now.
If anyone could help me out, it would certainly be appreciated.
Thanks
Shift and mask:
answer = value >> 12 & 0xFFFFFFFFFFF;

Java "Bit Shifting" Tutorial? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 8 years ago.
Improve this question
I would be thankful for a good tutorial, that explain for java newbies how in java all the "bit shifting" work.
I always stumble across it, but never understood how it works. It should explain all the operations and concepts that are possible with byteshifting/bitmanipulation in java.
This is just an example what I mean, (but I am looking for a tutorial that explains every possible operation):
byte b = (byte)(l >> (8 - i << 3));
Well, the official Java tutorial Bitwise and Bit Shift Operators covers the actual operations that are available in Java, and how to invoke them.
If you're wondering "what can I do with bit-shifting", then that's not Java specific, and since it's a low-level technique I'm not aware of any list of "cool things you can" do per se. It'd be worth becoming familiar with the definitions, and keeping your eyes open for other code where this is used, to see what they've done.
Note that often bit-twiddling is an efficiency gain at the expense of clarity. For example, a << 1 is usually the same as a * 2 but arguably less clear. Repeated XORs can swap two numbers without using a temporary variable, but it's generally considered better form to write the code more clearly with the temporary variable (or even better, in a utility method). So in this respect it's hard to give great examples, because you're not likely to achieve anything new or profound on an architecture level; it's all about the low-level details. (And I'd estimate that a vast number of uses of bit-twiddling "in the wild" are instances of premature optimisation.)
When using the shift operator, be very careful not to repeat a common error!!
As the following SO post suggests, the author of the accepted answer mentions:
"In some languages, applying the shift operators to any datatype smaller than int automatically resizes the operand to be an
int."
This is absolutely crucial to remember when operating on bytes for example, otherwise you may get unexpected results (as I did).
Given a byte with the following bit pattern:
1001 0000
When I tried to bit shift by 4, and assigned to an int, such as:
int value = byteValue >>> 4;
I would expect to have:
0000 1001 (or a value of 9)
But I would get a HUGE number! That's because the byteValue is casted to int BEFORE the bit shift operation, thus resulting in something like this instead:
1111 1111 1111 1111 1111 1111 1001
There is an infinite number of possible combinations. However they will be made up of one or more combinations of
>> shift right with sign extension.
>>> shift right with out sign extension.
<< shift left.
To get an understanding I suggest you write the binary numbers on paper and work out what happens. Trying to read it in a tutorial won't guarantee understanding. esp if they haven't helped so far.
There is simple but clear tutorial that I find useful here
It's not exactly a tutorial, but I have a personal library of bit-shifting functions in Java which you are very welcome to study!
Also if you do a google search for "bitwise tricks" you will find a lot of material. Many of these are in C/C++ but are generally trivially to convert to Java as most of the syntax is the same.
Here are the details of how bit shifting works.
There is some non-intuitive behavior that is not covered by the official tutorial. For instance, the right operand has a limited range (0-31 for int, 0-63 for long), and will not produce a warning if you exceed that range -- it will just truncate the bits (i.e. %32 or %64), which may give behavior other than you expect.
This site seems to give a pretty good tutorial on what you can do with bit manipulation (so not specific to java but since it is pretty easy to translate)
http://www.bogotobogo.com/cplusplus/quiz_bit_manipulation.html
The tutorial above provides
Bitwise Operations
Setting and Clearing a Bit
Displaying an Integer with Bits
Converting Decimal to Hex
The Number of Bits Set in an Integer (Number of Ones)
The Bit Set Position of an Integer
In-Place Integer Swap with Bit Manipulation
The Number of Bits Required to Convert an Integer A to Integer B
Swap Odd and Even Bits in an Integer
What (n & (n-1) == 0) is checking?
Two's Complement
Fliping n-th bit of an integer
Floating Point Number Bit Pattern
Bit pattern palindrome of an integer
Here's a file that has a bunch of java implementations
http://geekviewpoint.com/
These are two good tutorials i found while learning about bit shifting, they arent in java but most languages use the same operators and the theory is the same.
Bit twiddling
PHP Bitwise Tutorial by Jim Plush

Categories