Why am I getting -3 shouldn't I be getting +7 - java

So I'm doing this and I thought it was going to give me +7 but its giving me -3.
public class BitManipulation{
public static void main (String[] args){
System.out.println(~2 | 5 >> ((2 & 2)));
}
}

2 & 2 is 2.
So then you have 5 >> 2 which gives 1 (5 in binary is 101)
So we remain with ~2 | 1
~2 is inverting all the bits. For 8 binary digits (the same goes for 32 but let's keep things concise...) the bits inversion of 00000010 (2) is 11111101. Or-ing this with 1 doesn't change anything.
Now, 11111101 - when treated as a number it is interpreted in two's complement. In this system the most significant bit is the sign, and here it's 1 so the number is negative. To get the absolute value of the number in two's complement we need to invert the bits and add 1.
So inverting 11111101 gives 00000010, and adding 1 gives 00000011, which is 3. Recall the sign was minus, so there you have -3!!! :-)

Try printing off each step like so:
System.out.println(2 & 2);
You will learn that 2 & 2 = 2 (we are performing the bitwise "AND" function on two binary numbers => 0010 AND 0010 = 0010 which is 2), so plug that into the next step:
System.out.println(5 >> 2);
Now you have 5 >> 2 = 1 (we are shifting that binary number to the right padding with zeroes because the number is positive, so 0101 becomes 0001 or 1), and plug that into the final step:
System.out.println(~2 | 1);
And you get ~2 | 1 = -3 (we are performing a bitwise "NOT" followed by a bitwise "OR" operation so 0010 becomes 1101 I believe this is also where it becomes negative and -1101 OR 0001 gives us -1101 or -3)

Related

How does BitSet's set method work with bits shifting to the left?

Java's BitSet class has a method Set that sets a single bit to 1 (=true). The method source code is as follows:
public void set(int bitIndex) {
if (bitIndex < 0)
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
int wordIndex = wordIndex(bitIndex);
expandTo(wordIndex);
words[wordIndex] |= (1L << bitIndex); // Restores invariants
checkInvariants();
}
In addition to the checks, the method's core code is: words[wordIndex] |= (1L << bitIndex). I can clearly see in the assignment that the left part is the specific word that holds the relevant bit. However, I don't understand how the right part (the shifting left of the bit index) cause the setting of the requested (and only it) bit to 1. Could you please explain?
1L << bitIndex produces a long, whose bits are all 0s, except for one of the bits. The position of the "1" bit is determined by bitIndex. For example, if bitIndex is 10, then the 11th least significant bit is 1.
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0000 0000
Because the 1 is shifted to the left 10 times. In general, the (bitIndex mod 64 + 1)th least significant bit is the "1" bit.
This mask is then bitwise OR'ed with whatever is in words[wordIndex]. Every bit in words[wordIndex] stays the same because they are OR'ed with 0, except for the one place where it is a "1" in the mask. That bit in words[wordIndex] will become "1" no matter what it was originally, due to how OR works.
There are two parts of interest: 1L << bitIndex and words[wordIndex] |=.
The first part – 1L << bitIndex – shifts a bit some number of spots. Here's a table showing how that plays out with a few different numbers of shifting.
statement
decimal
binary
1L << 0
1
1
1L << 1
2
10
1L << 2
4
100
1L << 3
8
1000
1L << 4
16
10000
The second part – words[wordIndex] |= – takes whatever value was already at words[wordIndex] and uses bitwise "or" to include whatever bit was isolated from above. If that bit was already set (for that word), this operation wouldn't change anything. If the bit was 0, the "or" operation (|=) would set the bit to 1.
Remember that the left side is being ORed (|) with the bit and the right most bit (or the Least Significant Bit - LSB) is bit 0. An OR operator will set the specified one bit(s) in the source, to the same bits in the target, leaving the other bits unchanged. Here are some examples.
int bits = 1;
System.out.println(Integer.toBinaryString(bits));
bits |= 0b100_0000_0000; // set bit 10 to 1.
System.out.println(Integer.toBinaryString(bits));
prints
1
10000000001
^
bit 10
or do it like this
System.out.println(Integer.toBinaryString(bits));
bits = 1;
// or it can be done this way.
bits |= 1<<10; // 10 is the bitIndex in bits to set so it is shifted
// left to that position and the result is as before
System.out.println(Integer.toBinaryString(bits));
prints
10000000001
^
bit 10

Equivalent function for Math.signum(double) for int or long in Java

Is there an equivalent function for Math.signum(double) or Math.signum(float) in Java for other primitive numbers like int or long. I don't want to write code like
int sign = (int) Math.signum((double) intValue);
when there is a better alternative.
You can use it this way:
Integer.signum(int i) and Long.signum(long l)
Link to javadoc: https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#signum-int-
Just an addendum of some implementation details of that :
public static int signum(int i) {
// HD, Section 2-7
return (i >> 31) | (-i >>> 31);
}
Integer::signum says : I'll give you -1 if the number is negative, 0 if number is zero and 1 if number is positive. This is fairly trivial via some nested if/else for example.
Instead JDK uses a solution that is a bit more fancy. (x >> 31) | (-x >>> 31). Looks easy right? the first part : x >> 31 is signed shift to the right; it's called signed because it keeps the sign after the shift.
Suppose we live in a world where 4 bits numbers exist only (for simplicity).
We have 0100 (+4), a single shift 0100 >> 1 will make it 0010 (+2). Now, if our number is 1100 (-4; the first bit is the sign), a shift signed to the right : 1100 >> 1 is 1110 (-2). Do a division, but keep the sign.
Thus if we shift 31 times, we throw away the last 31 bits of the number, move the bit for the sign in the least significant position and keep the original sign. Or in simple words take the 31 bit, put it into 0 position and throw away everything else.
0 00000 ..... 11111
x --------------->0 // x is kept
ignore
The second part -x >>> 31 is a unsigned shift, meaning the sign is not kept when we shift.
For example 0100 >>> 1 (+4) will give you 0010 (+2). Nothing is really different so far from the signed shift and the example above. The interesting part comes when numbers are negative:
1100 (-4) and we try to shift it once : 1100 >>> 1, because the sign is not kept, we put zero in the most significant bit and move to the right, thus we get : 0110 (+6!).
In reality, taking 32 bits into the picture. -4 == 1111...111100 and we shift it to the right: sign is zero, everything else is moved to the right, thus: 0111...11110 or Integer.MAX_VALUE - 1.
System.out.println(-4 >>> 1);
System.out.println(Integer.MAX_VALUE - 1);
Thus the part x >>> 31 will move the sign bit into the least significant position, zeroing everything else. No matter the number you give it, you will always get 1 or 0.
1 00000 ..... 11111
x --------------->1 // x is "zeroed also"
ignore
And the addition of -x to that x >>> 31 is simply done so that | would work correctly satisfy our needed result.

Need help understanding this line

thank you in advance for this basic question.
I am going through a tutorial and I see this line.
int a = (n & 8) / 8
This is supposed to identify whether the fourth bit from the right is a binary representation of 0 or 1. I understand the concept of bits etc, but I do not understand what mathematical equation (if any) this represents.
Would anyone care to explain how this would be written in a mathematical equation? Also, please let me know if i am missing anything else in my understanding of this line. Thank you.
The expression ( n & 8 )
does Logical And of n with 1000 binary.
So that gets the 4th bit from right.
then dividing that by 8, shifts the value right 3 binary places. I.e. it moves the 4th bit to the rightmost place.
That is more clearly expressed as " >> 3"
So your overall expression would be something like:
(n AND 1000 ) >> 3
And that leaves the 4th bit of N in a temporary variable, as bit 0 (rightmost bit).
All the other bits will be zero because of the AND.
8 in decimal is 1000 in binary
so if you do bitwise AND with any number
n & 8
it will stay 8 only if the 4th bit is 1 and
if you divide it by 8 again it will return 1, zero otherwise
For example
for 9 (1001)
9 & 8
would be
1001
& 1000
------
1000
Now for the case where forth bit is 0
for 7 (0111)
7 & 8
would be
0111
& 1000
-----
0000
int a = (n & 8) / 8;
The n & 8 applys a logical AND mask to the 4th bit of n;
n: 11001010 // example value
8: 00001000
result: 00001000
Dividing that number by 8 brings the result to the lowest bit :
result: 00000001
Dividing a number by 2^n shifts the numbers n bits to the right (in the same way that multiplying by 2^n shifts bits to the left).
The result is assigned to variable a, which now contains 0 or 1, depending on the value of the 4th bit.
Bitwise operator works on bits and performs bit-by-bit operation. Assume if a = 60; and b = 13; now in binary format they will be as follows:
a = 0011 1100
b = 0000 1101
a&b=0000 1100
then a&b is also an integer which is further divided by 8 in your example.

How do bitwise operator results occur?

I'm quite surprised that I can't find an answer to this simple sounding question on Google. After checking about a dozen different pages I'm just going to ask here ...
According to this page, 3 & 5 result in 1. Also, 3 | 5 result in 7. The only question I have is simply:
How do we get 1 for 3 & 5?
How to we get 7 for 3 | 5?
Also, what about negative numbers?
How does 8 & -8 result in 8?
Sure enough, writing the following in java:
System.out.println(3&5);
System.out.println(3|5);
System.out.println(8&-8);
Produces this output:
1
7
8
But again, how are these results determined / calculated?
3 & 5:
0011
0101
----- AND
0001 == 1
3 | 5:
0011
0101
----- OR
0111 == 7
Negation in Java is defined to be two's complement negation (which is extremely common).
So -x = ~x + 1 = ~(x - 1).
8 & -8:
00001000 //8
11111000 //-8
-------- AND
00001000 // 8
Using the last definition of negation, the -1 first borrows through all rightmost zeroes (if there are any), setting them as it goes, until it hits a 1, which it resets, anything to the left of that is left unmodified. The complement then restores the rightmost zeroes and the rightmost one (all of which were effectively complemented by that -1), and complements everything to the left of the rightmost one:
00001000 // 8
00000111 // 8 - 1 = 7
11111000 // -8
Note that -8 is only 11111000 if you're working with 8 bit numbers. If had you more bits, there would be more 1's to the left. If you have only 4 bits, you run into some kind of trouble because -8 turns out to have the same representation as 8, and so -8 is (in 4 bit math) a number that is its own negative (like zero).
Actually, 8 is not a very good example, because it's too simple. Let's do 100 & -100 (hundred, not 4):
01100100 // 100
01100011 // 99
10011100 // -100
Now & with 100:
01100100 // 100
10011100 // -100
-------- AND
00000100 // 4
In general, x & -x isolates the rightmost 1. Neither the rightmost zeroes not the rightmost 1 are affected by negation, and so for only that part of the number, it looks like you're doing x & x (which is of course x). The upper part, to the left of the rightmost one, is complemented, so everywhere you had a 1 becomes 0, and everywhere you had a 1 becomes 0. 0 & 1 = 0, so that gives 0 everywhere.
3 & 5 => 1
3 in binary is 0011.
5 in binary is 0101.
apply the bitwise and
0011
& 0101
------
0001 => 1 in decimal
Take the same idea, along with the truth tables for each op, and apply them to your specific problems.
You need to turn the number into binary at that point you need to remember that "b1 and b2=1" only if they are both 1, and "b1 or b2=0" only if they are both 0.
So for example
5 or 3 = 101 or 011 = 111 = 7
5 and 3 = 101 and 011 = 001 = 1

System.out.println(16 >>> 3)? [duplicate]

This question already has answers here:
Difference between >>> and >>
(9 answers)
Closed 9 years ago.
I try the code
System.out.println( 16 >>> 3);
and the output is 2 !
but how does this work? What is the syntax?
16 >> 3 is a bitshift to the right, and is equivalent to dividing by 8 (2 ** 3).
16 -> 00010000
^
\
\
2 -> 00000010
This is called right-shift with zero-fill (also called - unsigned right shift).
To make it easy to understand, for every shift, your number is divided by 2. So:
16 >>> 3 == 16 / 2^3 == 16 / 8 == 2
For more details see, JLS - Shift Operators.
For real visualization, take a look at the bit representation of the two numbers:
16 - 00010000
16 >>> 3 - 00000010 == 2
Another note, the 3 chevrons indicate an unsigned right bit shift. Although it does not make a difference in this example...
The extra > indicates the sign is not reserved, an example:
-128 >> 2 = -128 / 2^2 = -32
The signed bit is retained giving:
(1) 10000000 >> 2 = (1) 100000
11111111 11111111 11111111 10000000 >> 2 = 1111111 11111111 11111111 11100000
If >>> is used then the signed bit is also shifted converting it to a positive number.
-128 >>> 2 = 536870896
11111111 11111111 11111111 10000000 >> 2 = 0011111 11111111 11111111 11100000
The >>> operator is performing an unsigned right-shift of bits, when applied to an integer it has the effect of dividing by two. In particular, if the integer is a power of two, each right-shift exactly halves the value. For example:
16 >>> 1 // returns 8
16 >>> 2 // returns 4
16 >>> 3 // returns 2
In binary form, 16 is represented as 10000. If we shift the value three times to the right it ends up as 00010, which is 2. Also, take a look at the Java tutorial.
16 in binary is 00010000. You are shifting the bits right three positions which results in 00000010 which is 2
This is a bit shift, which is dividing by 2^3 (due to shifting by 3 positions) and truncating(rounding down) as we are not doing fillaround.
When using >>> we move to the right and divide.
When using <<< it goes opposite, so you'd multiply by the correct power of 2.
Bit shifts are a type of bitwise operation that operates on a primitive(almost always number's) bits directly.
It's an unsigned right shift operator, and the above shifts 3 times.
i.e. it divides by 2 each time, giving you 2.
See here for more information on Java operators.
You're using a bitwise shift consult this post
In binary, every 0 is an increasing magnitude of the power 2 for example:
10000 = 16
01000 = 8
00100 = 4
00010 = 2
00001 = 1
The expression 16 >>> 3 in java is saying to move the bit over 3 places, so we are left with 2.

Categories