Shifting a single nibble in Java BigInteger? - java

I have a Java BigInteger containing two bytes (ex: 1000000100110111). I would like to shift only a single nibble, the right-most nibble in the left byte (in bold below) to the left by one bit:
1000 0001 00110111
Making the result after the shift:
1000 0010 00110111
Any thoughts on the best way to go about doing this?
Thanks,
Chris

If you only want to shift a single bit, you should rather clear the old and set the new:
bigint.clearBit(n-1)
.setBit(n)
If you want to shift those next to four most left bits, you could bitmap them out, shift them, and then or them back:
bigint.and(0xf0ff).or(bigint.and(0x0f00).shiftLeft(1))
Or for clarity:
unshifted = bigint.and(0xf0ff);
shifted = bigint.and(0x0f00).shiftLeft(1);
result = unshifted.or(shifted);
If you don't want 1100 1111 to become 1101 1110 (notice the spill), you can apply the bitmap again on the shifted, before the or.

Related

Drop bits by shifting left and right in Java

Is it possible to "drop" a couple of most significant bits of a byte number by executing shifting operations in Java?
The idea looks like this:
1010 1111 -> (<<2) -> 1011 1100 -> (>>2) -> 0010 1111 => 2 bits were dropped.
I think the only thing that you're missing from your suggestion is that the right shift should use the unsigned right shift operator, >>>:
int result = (input << n) >>> n;

Where is the 6th bit in 16-bit char value?

There are two examples of bit switching in the book Java: A Beginners Guide. In both cases, the author writes about switching the 6th bit but he demonstrates it on 16 digits. Both examples use bitwise operators for changing the letter case.
In the first, he operates on lower case characters: 'a' & 65503 changes the char to 'A'. It is described as switching the 6th bit off. The problem is the number 65503 equals 1111 1111 1101 1111 in binary. Hence the 11th digit/bit is switched off (he even shows the number there).
The same he does for uppercase letters and bitwise OR operator: 'a' | 32 does the trick. The number 32 equals 0000 0000 0010 0000 in binary.
In both cases, the change does make sense. I just don’t understand why the author writes about the 6th bit. I would understand if it was for the 11th bit or 6th pair (in that case I would expect the turning it off completely as 00 or 11.
Any clarification more than welcome.
The location of the 6th bit could be in a few locations, depending upon the convention you adopt:
Counting the left-most bit as zero-th, and moving right
Counting the left-most bit as first, and moving right
Counting the right-most bit as zero-th, and moving left
Counting the right-most bit as first, and moving left
(Other conventions may be available)
The author should really have defined which of these he was using, for clarity (and may do, elsewhere in the text). But apparently, he means item 4.
0000 0000 0010 0000
65 4321
The 0's and 1's that make up a binary number are called bits. The bits start from the right and go left:
So 0010 0000:
8th bit 7th bit 6th bit 5th bit 4th bit 3rd bit 2nd bit 1st bit
0 0 1 0 0 0 0 0
Decimal is read the same way as binary:
3754 in decimal:
(3 x 1000) | (7 x 100) | (5 x 10) | (4 x 1)
156 in binary = 10011100
(1 x 128)|(0 x 64)|(0 x 32)|(1 x 16)|(1 x 8)|(0 x 4)|(0 x 2)|(0 x 1)
In decimal you add a new column to to the start of the number (i.e the right) when you reach a power of 10.
In binary you add a new column when you reach a power of 2.
Does this help explain it?

Java - How to Extract Certain Portions of Bits Using Bit Mask?

This is the first time I am looking at bitwise operations and bit mask. I have seen some examples using C and C++, but I am looking for clarification using Java.
I have the following 32-bit string
0000 0000 1010 0110 0011 1000 0010 0000
But I want to extract bits 21 through 25 in bold (00101) and ignore everything else. In the end, I want my output result to be integer 5 (0101 in binary)
Using bit mask, what approach I could use to get just that bit portion as my output result?
If you really have a String, take the two substrings (00 and 101), concatenate them, and use Integer.parseInt with a radix of two:
int bits = Integer.parseInt(str.substring(7, 9) + str.substring(10, 13), 2);
If you have an int, use a logical right shift, then use & with a bit mask (0b signifies binary notation).
int bits = (n >>> 21) & 0b11111;

Binary presentation of negative integer in Java

Please, help me to understand binary presentation of negative integers.
For example we have 5.
Binary presentation of 5 is 00000000.00000000.00000000.00000101.
And as I understand binary presentation of -5 should be like 10000000.00000000.00000000.00000101.
But output is 11111111.11111111.11111111.11111011.
I have 2 question:
1) Why here is so much 1 bits.
2) What I really cant understand it last 3 bits 011. It looks like 3. Even +1 or -1 it'll be 100 or 010
Thanks
Your understanding of what those negative numbers should look like is flawed. Java uses two's complement for negative numbers and the basic rule is to take the positive, invert all bits then add one. That gets you the negative.
Hence five is, as you state:
0000...00000101
Inverting that gives you:
1111...11111010
Then adding one gives:
1111...11111011
The bit pattern you have shown for -5 is what's called sign/magnitude, where you negate a number simply by flipping the leftmost bit. That's allowed in C implementations as one of the three possibilities(a), but Java uses two's complement only (for its negative integers).
(a) But keep in mind there are current efforts in both C and C++ to remove the other two encoding types and allow only two's complement.
And as I understand binary presentation of -5 should be like 10000000.00000000.00000000.00000101.
That would be right if Java used a Sign and Magnitude representation for integers. However, Java uses Two's Complement representation, so the rest of the bits are changed in accordance with the rules of that representation.
The idea behind two's complement representation is that when you add a number in such representation to another value dropping the extra bit on the most significant end, the result would be as if you subtracted a positive number of the same magnitude.
You can illustrate this with decimal numbers. In a two-digit representation, the value of 99 would behave like -1, 98 would be like -2, 97 like -3, and so on. For example, if you drop the top digit in 23 + 99 = [1]22, so 99 behaved like -1. 23 + 98 = [1]21, so 98 behaved like -2.
This works the same way with two's complement representation of binary numbers, except you would drop the extra bit at the top.
http://en.wikipedia.org/wiki/Two%27s_complement
The way negative numbers are stored is that the most significant bit (e.g. the bit representing 2^31 for a 32 bit number) is regarded as negative. So if you stored all 1s, you would add up
(-2^31) + 2^30 + 2^29 + ... + 2^1 + 2^0
which makes -1.
Small negative numbers will be mostly ones under this representation.
Here is an example for 2's compliment:
If you have -30, and want to represent it in 2's complement, you take the binary representation of 30:
0000 0000 0000 0000 0000 0000 0001 1110
Invert the digits.
1111 1111 1111 1111 1111 1111 1110 0001
And add one.
1111 1111 1111 1111 1111 1111 1110 0010
Converted back into hex, this is 0xFFFFFFE2. And indeed, suppose you have this code:
#include <stdio.h>
int main() {
int myInt;
myInt = 0xFFFFFFE2;
printf("%d\n",myInt);
return 0;
}
That should yield an output of -30. Try it out if you like.
With two's complement it's true that a MSB of 1 indicates a negative number. But the remaining bits are not the binary representation of its value. On the other hand, if the MSB is 0 the remaining bits represent the binary value. But it cannot be said that the number is positive then. Zero is neither positive nor negative.
This picture helped me to understand the principle when I started to learn that there are more representations of numbers than with 0..9:
0
-1 000 1
111 001
-2 110 010 2
101 011
-3 100 3
-4

Why does a signed shift right bring in 1s instead of just holding a 1 in the most significant spot?

...and bring in 0s.
For example:
1111 0110 >> 2
gives
11 1111 01
according to some notes.
Why are 1s brought in? Why not just hold the left most bit at 1 and bring 0s in?
Isn't shifting to the right sort of like dividing by 2? If so shouldn't 0s be brought in?
You want a right shift to be the same as dividing by 2. Assuming that’s a signed 8-bit quantity, this is -128:
1000 0000
This is -64:
1100 0000
So this is a counterexample to your suggestion.
It's called "sign extension" and it's there exactly in order to have the effect of dividing by two. If the leftmost bit became 0, the sign of the originally negative number would change into positive. If only the leftmost bit was kept one, and further bits changed to zero, the result would have nothing to do with division by two.
If you want zeros to be prepended on the left, there is a special operator for that: >>>.
NB Java has only one unsigned integer quantity, and it is char. On this data type, >> works by prepending zeros on the left.

Categories