Understanding java BigInteger.bitCount method on negative number - java

This method BigInteger.bitCount() "Returns the number of bits in the two's complement representation of this BigInteger that differ from its sign bit."
If the number is positive, it is the count of 1 bits in the number.
I have difficulty to get the negative number right.
For example, number -1377605392 's binary representation is -1010010000111001001011100010000. It has 12 1s and 19 0s.
But java code BigInteger.valueOf((long)-1377605392) give result of 15!!
How does this 15 is calculated?

The two's complement representation of a binary number means:
subtract 1
switch all 1 to 0 and 0 to 1
Compare the two's complement of -1377605392 with the corresponding positive number:
1111111111111111111111111111111110101101111000110110100011110000
0000000000000000000000000000000001010010000111001001011100010000
As you can see, all bits are flipped, except the trailing zeroes.
However, in BigInteger, negative numbers are stored as the absolute (that is: positive) value with a separate sign-bit, so to count the number of 0 in a negative number, the pasted code counts the number of 1 in the absolute value, adds the number of trailing zeroes (which are still 0) and subtracts 1 (for the last 1 which is still there)
The reason for using two's complement is that it makes basic arithmetics really simple, and the logic can ignore the sign. For example (using 8-bit numbers for simplicity):
6 = 00000110
-2 = 11111110
4 = 00000100 (adding together with carry)
You should do som excercises on paper with smaller numbers to understand how this works.

Related

why the result of a negative number in shift operator >> is different from the normal division?

I am trying to underestand the concept of shift operators,
and I was testing the following code:
15 >> 2;
- 15 >> 2
The result from the first statement is 3 as 15/4=3
but the result from the second statement is -4.
I understand that the binary of -15 is 11110001 and when we shift 2 to the right, we have 11111100, and this is -4. but I don't underestand why the result is different from the simple division which is -15/4= -3 and not -4?
please guide me why this happened?
The shift operator drops any mathematical fraction by taking the floor, not the truncation. The JLS, Section 15.19, states:
The value of n >> s is n right-shifted s bit positions with sign-extension. The resulting value is floor(n / 2s). For non-negative values of n, this is equivalent to truncating integer division, as computed by the integer division operator /, by two to the power s.
The floor of -3.75 is -4 whereas truncation would have yielded -3.
When the value is right-shifted, bits are lost as they are shifted "off the end" of the value. This is what is responsible for the floor operation.
-15: 11110001
-4: 11111100 // The rightmost 1 bit above is lost, resulting in what looks like the floor function.
Java uses two's complement to represent negative numbers.
Shifting right by n bits on a two's complement signed binary number has the effect of dividing it by 2n, but it always rounds down (towards negative infinity). This is different from the way rounding is usually done in signed integer division (which rounds towards 0).

Question related to range of the primitive datatypes

In java, short has range of -128 to 127. Why is it not -127 to 127 ? Considering one bit is used for storing the sign of the number, the negative limit should have been -127 which is sum of 2^6+2^5+2^4+2^3+2^2+2^1+2^0 ? What am I missing in my calculations ?
I will assume you meant byte rather than short, as short has a range of -32768 to 32767.
You appear to be under the impression that, for integer types (including short), a negative number is represented with a signed bit and the rest of the number as normal. So -1 would be represented as 1000.0001 (dot added for readability). This, however, is incorrect.
In reality, -1 is represented as 1111.1111, and 1000.0000 is actually -128 (and not -0, which doesn't exist for this type). This is to keep the arithmetic consistent across all values.
You are using 8-Bits to store that in the memory of the computer. This would simply 0 to 255. Considering that you also want negative numbers, you must change the way of looking on these numbers.
Let's say that we take the 8th bit as an indicator for negativity. The negative number would be the negation of the positive number. This would let us display numbers from -127 to 127, but there would be two ways to display the 0: 1111 1111 and 0000 0000. This is called One's Complement.
Because engineers wanted to use all the available space, the came up with a new idea. To convert a position number in to a negative ( * - 1) they decided to fully negate the number and increment it by one. This would give them the possibility of using the whole 256 range. That's the Two's Complement. There are 128 negative numbers + 1 Zero + 127 positive numbers, which makes 256 numbers.
Your calculations are wrong. Total possibilities are 2^8 and that is equal to 256. From -128 to 127 because we count 0 as one of those numbers. 128+128 = 256. But 256 + '0' = 257. So it has to be from -128 to 127.

Calculate the maximum value of a Java Double (5)?

Calculating this value for an long is easy:
It is simply 2 to the power of n-1, and than minus 1. n is the number of bits in the type. For a long this is defined as 64 bits. Because we must use represent negative numbers as well, we use n-1 instead of n. Because 0 must be accounted for, we subtract 1. So the maximum value is:
MAX = 2^(n-1)-1
what it the equivalent thought process, for a double:
Double.MAX_VALUE
comes to be
1.7976931348623157E308
The maximum finite value for a double is, in hexadecimal format, 0x1.fffffffffffffp1023, representing the product of a number just below 2 (1.ff… in hexadecimal notation) by 21023. When written this way, is is easy to see that it is made of the largest possible significand and the largest possible exponent, in a way very similar to the way you build the largest possible long in your question.
If you want a formula where all numbers are written in the decimal notation, here is one:
Double.MAX_VALUE = (2 - 1/252) * 21023
Or if you prefer a formula that makes it clear that Double.MAX_VALUE is an integer:
Double.MAX_VALUE = 21024 - 2971
If we look at the representation provided by Oracle:
0x1.fffffffffffffp1023
or
(2-2^-52)·2^1023
We can see that
fffffffffffff
is 13 hexadecimal digits that can be represented as 52 binary digits ( 13 * 4 ).
If each is set to 1 as it is ( F = 1111 ), we obtain the maximum fractional part.
The fractional part is always 52 bits as defined by
http://en.wikipedia.org/wiki/Double-precision_floating-point_format
1 bit is for sign
and the remaining 11 bits make up the exponent.
Because the exponent must be both positive and negative and it must represent 0, it to can have a maximum value of:
2^10 - 1
or
1023
Doubles (and floats) are represented internally as binary fractions according to the IEEE standard 754
and can therefore not represent decimal fractions exactly:
http://mindprod.com/jgloss/floatingpoint.html
http://www.math.byu.edu/~schow/work/IEEEFloatingPoint.htm
http://en.wikipedia.org/wiki/Computer_numbering_formats
So there is no equivalent calculation.
Just take a look at the documentation. Basically, the MAX_VALUE computation for Double uses a different formula because of the finite number of real numbers that can be represented on 64 bits. For an extensive justification, you can consult this article about data representation.

Why is absolute of Integer.MIN_VALUE equivalent to Integer.MIN_VALUE

In java when I say Integer i = Math.abs(Integer.MIN_VALUE). I get the same value as the answer,which means i contains Integer.MIN_VALUE.
I have verified the same in C++ as well.
Why this behavior?
Read this in Effective Java by Joshua Bloch.
I found the answer for this question and here is the explanation:
Computers work with binary arithmentic, the logic of Math.abs in java or the absolute function in any language is like below:
if(num >= 0)
return num;
else
return (2's complement of the num);
Note : How to find 2's complement
For a given number, we find it's 1's complement first and then add 1 to it. For e.g.
Consider our number to be 10101
1's complement= 01010
2's complement= 01011 (added 1 to the 1`s complement)
Now, for the sake of making it easy and clear, let us say that our Integer(signed) size is 3 bit, then here is the possible list of numbers which can be produced using the four bits:
000 --> 0 (0)
001 --> 1 (1)
010 --> 2 (2)
011 --> 3 (3)
100 --> 4 (-4)
101 --> 5 (-3)
110 --> 6 (-2)
111 --> 7 (-1)
Now that this is signed, it means half of the numbers are negative and the other half are positive(The negative numbers are the ones with the first bit 1). Let us start from 000 and try to find its negative number, it would be the two's complement of 000.
2's complement of `000` = 1 + `111` = `000`
2's complement of `001` = 1 + `110` = `111`
2's complement of `010` = 1 + `101` = `110`
2's complement of `011` = 1 + `100` = `101`
2's complement of `100` = 1 + `011` = `100`
2's complement of `101` = 1 + `010` = `011`
2's complement of `110` = 1 + `001` = `010`
2's complement of `111` = 1 + `000` = `001`
From the above demonstration, we find that 2's complement of 111(-1) is 001(1), similarly 2's complement of 110(-2) is 010(2), 2's complement of 101(-3) is 011(3) and 2's complement of 100(-4) is 100(-4) and as we can see that -4 is the smallest negative number possible using 3 bits.
This is the reason why absolute of Integer.MIN_VALUE is Integer.MIN_VALUE.
There is an inherent asymmetry that is the root cause of this effect. The number of 32-bit bit patterns is even. One of those patterns is used for zero. That leaves an odd number of non-zero values. The number of positive values and the number of negative values cannot be equal because their sum is odd.
In the 2's complement representation used for Java integers, the number of negative numbers is one greater than the number of positive numbers. Each negative number other than Integer.MIN_VALUE corresponds to a positive number that is both its negation and its absolute value. Integer.MIN_VALUE is left over, with no corresponding positive int. Math.abs and negation map it to itself.
Why this behavior?
It is a mathematical consequence of the choice of representation used in all modern computers.
Here's an informal proof of why it has to be that way.
A signed binary number representation with N bits has 2N possible values; i.e. a set integers with an even number of elements.
Remove zero from the set. The set is now has an odd number of elements.
Now remove all pairs of numbers of the form {n, -n}. Each time we remove a pair of numbers, the set still contains an odd number of elements.
We are now left with a set that contains an odd number of integers for which n is in the set, but -n is not in the set. Since the set size is odd, it cannot be empty; i.e. there is at least one number with this property.
In the representations specified by Java (and indeed used all other practical languages), integer types have 2N-1 negative values and 2N-1 - 1 values greater than zero. The value that has the strange property is MIN_VALUE. This representation is called two's complement.
Strictly speaking, an integer representation doesn't have to have this anomaly:
It is possible to have two zeros (-0 and +0); e.g. signed magnitude or one's complement representations. (This invalidates step 2 of the proof: there are now 2 zeros to remove.)
It is possible to exclude -2N-1; i.e. make it an illegal value. (This invalidates step 1 of the proof: the initial set now has an odd number of values.)
It is possible to specify integer arithmetic so that (for example) negating MIN_VALUE raises an exception. For instance Math.abs(Integer.MIN_VALUE) would throw an exception.
However, all of these things have significant performance implications, especially since modern computer hardware only supports twos-complement arithmetic natively. They also have issues in relation to writing reliable integer codes ...
Math.abs(int) docs says If the argument is negative, the negation of the argument is returned. JLS 15.15.4. Unary Minus Operator says For all integer values x, -x equals (~x)+1.
-Integer.MIN_VALUE = ~Integer.MIN_VALUE + 1 = ~0x80000000 + 1 = 0x7FFFFFFF + 1 = 0x80000000 = Integer.MIN_VALUE
You might expect that absolute value of Integer.MIN_VALUE would be Integer.MAX_VALUE + 1, but this value is out of primitive int size. And Integer.MAX_VALUE + 1 is Integer.MIN_VALUE again. That's all.
This is because of the way two's-complement number systems work. Integer.MIN_VALUE corresponds to 0x80000000. The standard way to negate it is to take its ones' complement (0x7FFFFFFF in this case) and add 1, and in this case it would overflow back to 0x80000000.

Why does the sign bit not affect the Integer.MAX_VALUE but affects the MIN Value?

System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
Prints:
2147483647
-2147483648
Why is the max value 2^31 -1 (the sign bit is 0 and does not add to the value of the number) and yet the min value is just -2^31 (the sign bit is 1 and does add to the value then??).
Think about it this way: you have as many binary patterns with the sign bit set to 1 as the number of binary patterns with the sign bit set to 0. However, you also need to represent zero, which is neither positive nor negative. Since zero is represented as a pattern of all zeros, it deducts from the set of positive numbers representable with the given number of bits, so the count of representable negative numbers is going to be greater by one.
The sign bit does not add to the value. You can represent 2^32 different values with 32-bits. Hovewer, one of those values is 0; so there are 2^31 negative values, 2^31 - 1 positive values and 0, which all add up to 2^32 different values. Since the sign bit of 0 is also 0, it is only natural that the number of positive values are one less then the number of negative values.

Categories

Resources