Why maximum integer number multiplication gives 1 as result - java

I think much explanation is not required, why below calculation gives result as 1?
int a = 2147483647;
int b = 2147483647;
int c = a * b;
long d = a * b;
double e = a * b;
System.out.println(c); //1
System.out.println(d); //1
System.out.println(e); //1.0

The binary representation of the integer number 2147483647 is as following:
01111111 11111111 11111111 11111111
Multiplying this with itself results in the number 4611686014132420609 whose binary representation is:
00111111 11111111 11111111 11111111 00000000 00000000 00000000 00000001
This is too large for the int type which has only 32 bits. The multiplication of a * b is done as an integer multiplication only, regardless of the variable's type to which the result is assigned (which might do a widening conversion, but only after the multiplication).
So, the result simply cuts off all bits that do not fit into the 32 bits, leaving only the following result:
00000000 00000000 00000000 00000001
And this simply is the value 1.
If you want keep the information, you must do the multiplication with the long type which has 64 bits:
long a = 2147483647;
long b = 2147483647;
long mult = a * b;
System.out.println((int) mult); // 1
System.out.println(mult); // 4611686014132420609
System.out.println((double) mult); // 4.6116860141324206E18
If you need more bits for a calculation you might consider BigInteger (for integral numbers) or BigDecimal (for decmial numbers).

2147483647 * 2147483647 = 4611686014132420609
Which in Hexa = ‭3FFFFFFF 00000001‬, after truncation only 00000001 remains which represents 1.

First of all, the reason that the three attempts all give the same answer is that they are all performing 32 bit multiplications and the multiplication overflows, resulting in "loss of information". The overflow / loss of information happens before the value of the RHS1 expression is assigned to the variable on the LHS.
In the 2nd and 3rd case you could cause the expression to be evaluated using 64 bit or floating point:
int c = a * b;
long d = ((long) a) * b;
double e = ((double) a) * b;
and you would not get overflow.
As to why you get overflow in the 32 bit case, that is simple. The result is larger than 32 bits. The other answers explain why the answer is 1.
Just for fun, here is an informal proof.
Assume that we are talking about a modular number system with numbers in the range 2N-1 to 2N-1 - 1. In such a number system, X * 2N maps to zero ... for all integers X.
If we multiply the max value by itself we get
(2N-1 - 1) * (2N-1 - 1)
-> 22N-2 - 2 * 2N-1 + 1
-> 22N-2 - 2N + 1
Now map that into the original range:
22N-2 maps to 0
2N maps 0
1 maps to 1
0 + 0 + 0 -> 1
1 - LHS == left hand side, RHS == right hand side.

What you are seeing is simply the result of integer overflow, which follows this rule:
Integer.MAX_VALUE + 1 = Integer.MIN_VALUE
One way to see what is happening is to contrive Java's int type as ranging from -7 to 7, with the same rule still applying. Let's see what happens when we multiply 7*7:
7 + 7 = 14 -> -2 (7 x 2)
-2 + 7 = 5 (7 x 3)
5 + 7 = 12 -> -4 (7 x 4)
-4 + 7 = 3 (7 x 5)
3 + 7 = 10 -> -6 (7 x 6)
-6 + 7 = 1 (7 x 7, one is leftover)
The same thing is happening in your code, with 2147483647 overflowing according to:
2147483647 + 1 = -2147483648

Because:
2147483647 * 2147483647 = 4611686014132420609
Integer capacity = 4294967295
4611686014132420609 % 4294967295 = 1

integer has only 3 byte memory allocation as well as double has 8 byte memory allocation your multiplication is so large than its give only starting which has (0000 0001)2 = 1

Related

Why does Integer.MAX_VALUE*2 returns -2? [duplicate]

This question already has answers here:
Multiplication of Integer.MAX_VALUE in Java [duplicate]
(3 answers)
Closed 4 years ago.
I was looking for a value of i where i==i+1 should always be true. Some others used double and float to find a solution to the problem.
I was trying to answer to a question on stack overflow. And thought about integers, trying to see if that could be possible too.
But while manipulating Integer.MAX_VALUE and Integer.MIN_VALUE many times, I found this strange behavior:
Integer.MAX_VALUE + 1 == Integer.MIN_VALUE
But Integer.MAX_VALUE * 2 == -2 and Integer.MAX_VALUE * 4 == -4
This happens only if I use even values like (2,4,6,8,10,12...). When I use odd values except 1, this happens:
Integer.MAX_VALUE * n == Integer.MAX_VALUE - n + 1 where n != Integer.MIN_VALUE and n > Integer.MIN_VALUE
Why is this behaving so? Is there something I am missing?
EDIT: I saw someone flagging the question as duplicate but navigating to the referred link, my question is different.
If it overflows, it goes back to the minimum value and continues from >there. If it underflows, it goes back to the maximum value and continues >from there.
I've carefully read answers from there but none of them explained why:
Integer.MAX_VALUE*x should be -x if x is an even number and Integer.MAX_VALUE*y should be Integer.MAX_VALUE-y+1 if y is an odd number.
That's exactly what is confusing me the most.
That's because Java's signed integers follow two's complement representation.
In a two's complement representation, negative numbers are represented as an N-bit complement of their corresponding positive value, i.e. their sum modulo 2n is 0.
Integer.MAX_VALUE is 2147483647 (hex 0x7FFFFFFF).
When multiplied, it overflows, and what remains is the lowest 32 bits (i.e. modulo 232):
0x7FFFFFFF * 2 = 0x0FFFFFFFE (mod32 = 0xFFFFFFFE = -2)
0x7FFFFFFF * 3 = 0x17FFFFFFD (mod32 = 0x7FFFFFFD = 2147483645)
0x7FFFFFFF * 4 = 0x1FFFFFFFC (mod32 = 0xFFFFFFFC = -4)
0x7FFFFFFF * 5 = 0x27FFFFFFB (mod32 = 0x7FFFFFFB = 2147483643)
0x7FFFFFFF * 6 = 0x2FFFFFFFA (mod32 = 0xFFFFFFFA = -6)
0x7FFFFFFF * 7 = 0x37FFFFFF9 (mod32 = 0x7FFFFFF9 = 2147483641)
An interesting property of two's complement representation is that the highest bit corresponds to the sign of the value.
Notice how the leftmost 7 results in alternating 0/1 bit 31. That bit happens to control the sign of the result, hence the alternating sign.
Why 0x7FFFFFFF * 2 is -2 is because 0x7FFFFFFF in a 31-bit representation (the largest possible representation without overflowing) is -1. And -1 * 2 = -2.
You can achieve a similar result if you take Long.MAX_VALUE and cast the result to int:
long x = Long.MAX_VALUE;
for (int i = 2; i < 8; i++) {
System.out.println((int)(x * i));
}
Just prints:
-2
-3
-4
-5
-6
-7
Now bit 31 isn't alternating anymore so we get stable results.
2147483647 is the max value, now try executing below set of instructions:
int i = 2147483647;
i++;
System.out.println(i);//prints -2147483647 as the 32 bit limit exceeds
binary equivalent of 2147483647 is 01111111111111111111111111111111
binary equivalent of 2 is 00000000000000000000000000000010
binary addition is 110000000000000000000000000000000
NOTE: The last bit at left stands for sign, int being 32 bit signed integer
thus, the number becomes -2147483647
i++;
System.out.println(i); // prints -2147483647
on the same lines, 2147483647 * 2 is actually -> 2147483647 + 2147483647
int j = 2147483647;
j += 2147483647;
System.out.println(j); // prints -2
and thus you answer.
now when you do 2147483647 * 3,
it is:
2147483647 + 2147483647 + 2147483647 = -2 + 2147483647 = 2147483645

Scala reduce and fold returns 0 instead of a value

Hey I have a case where I tried to run this on REPL:
(1 to 100).toList.reduce(_*_)
And it Returned me 0. I did not understand this behavior. If the Int has been overflowed it should have returned any negative or positive number. I got curious hence I tried this:
(1 to 100).toList.fold(1)(_*_)
It still returned me 0
Then I tried this:
(1 to 100).toList.fold(1)((a,b) => { println(s"dd::::$a:::$b"); a*b })
It returns me :
scala> res0.toList.fold(1)((a,b) => { println(s"dd::::$a:::$b"); a*b })
dd::::1:::1
dd::::1:::2
dd::::2:::3
dd::::6:::4
dd::::24:::5
dd::::120:::6
dd::::720:::7
dd::::5040:::8
dd::::40320:::9
dd::::362880:::10
dd::::3628800:::11
dd::::39916800:::12
dd::::479001600:::13
dd::::1932053504:::14
dd::::1278945280:::15
dd::::2004310016:::16
dd::::2004189184:::17
dd::::-288522240:::18
dd::::-898433024:::19
dd::::109641728:::20
dd::::-2102132736:::21
dd::::-1195114496:::22
dd::::-522715136:::23
dd::::862453760:::24
dd::::-775946240:::25
dd::::2076180480:::26
dd::::-1853882368:::27
dd::::1484783616:::28
dd::::-1375731712:::29
dd::::-1241513984:::30
dd::::1409286144:::31
dd::::738197504:::32
dd::::-2147483648:::33
dd::::-2147483648:::34
dd::::0:::35
dd::::0:::36
dd::::0:::37
dd::::0:::38
dd::::0:::39
dd::::0:::40
dd::::0:::41
dd::::0:::42
dd::::0:::43
dd::::0:::44
dd::::0:::45
dd::::0:::46
dd::::0:::47
dd::::0:::48
dd::::0:::49
dd::::0:::50
dd::::0:::51
dd::::0:::52
dd::::0:::53
dd::::0:::54
dd::::0:::55
dd::::0:::56
dd::::0:::57
dd::::0:::58
dd::::0:::59
dd::::0:::60
dd::::0:::61
dd::::0:::62
dd::::0:::63
dd::::0:::64
dd::::0:::65
dd::::0:::66
dd::::0:::67
dd::::0:::68
dd::::0:::69
dd::::0:::70
dd::::0:::71
dd::::0:::72
dd::::0:::73
dd::::0:::74
dd::::0:::75
dd::::0:::76
dd::::0:::77
dd::::0:::78
dd::::0:::79
dd::::0:::80
dd::::0:::81
dd::::0:::82
dd::::0:::83
dd::::0:::84
dd::::0:::85
dd::::0:::86
dd::::0:::87
dd::::0:::88
dd::::0:::89
dd::::0:::90
dd::::0:::91
dd::::0:::92
dd::::0:::93
dd::::0:::94
dd::::0:::95
dd::::0:::96
dd::::0:::97
dd::::0:::98
dd::::0:::99
dd::::0:::100
res5: Int = 0
I do not understand this behavior clearly. Could anyone please help !Thanks
I do not understand this behavior clearly
Generally, what you're experiencing is arithmetic overflow. If you want to pinpoint exactly why the 34th value returns 0, then doing the calculation by hand can help.
The result of the 33th product is -2147483648, which is:
64bit hex: 0x‭FFFFFFFF80000000‬
32bit hex: 0x80000000
64bit binary: ‭1111111111111111111111111111111110000000000000000000000000000000‬
32bit binary: 10000000000000000000000000000000
We multiply it by 34, we get:
64bit hex: ‭0xFFFFFFEF00000000‬
32bit hex: 0x00000000‬
64bit binary: ‭1111111111111111111111111110111100000000000000000000000000000000‬
32bit binary: 00000000000000000000000000000000‬
Since Int looks at the lower 32bit, you get 0. Everything on from here will result in 0 since that's the accumulators value and you're doing multiplication.
Execute the following to understand what is going on:
val x = Int.MinValue
x - 1 // = Int.MaxValue-1
x + x // = 0
x + x + x // = Int.MinValue
When you subtract from Int.MinValue you start from the max value. If you subtract abs(MinValue) from MinValue (MinValue * 2) you will be doing abs(MinValue) steps left from MaxValue which will bring you to 0.
This behaviour leads you to a situation in which MinValue * even number = 0 and MinValue * odd number = MinValue
Both behaviours occurred on lines 33-34, and of course as soon as one of you results is 0, all of your other results will be 0 as well.
In your output there is one line like: dd::::-2147483648:::34, which produces 0 as output. Hence all subsequent multiplications result in 0.
Reason being -2147483648 in minimum value of Int (Int.MinValue).
scala> Int.MinValue
res6: Int = -2147483648
If you try -2147483648 + -2147483648 in REPL, because of Int overflow, output will be 0. Now when you do -2147483648 * 34 it is equivalent to (-2147483648 + (-2147483648)) * 17, hence output is 0.

Java Code Integer Output

I am trying to write a code which raises 2 to
the powers of 0, 1, 2. 3. 4, .... n
For example for 31 it would reproduce the following results:
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192
16384 32768 65536 131072 262144 524288 1048576 2097152
4194304 8388608 16777216 33554432 67108864 134217728
268435456 536870912 1073741824 2147483648
I have written the following code:
public class Powersof2 {
public static void printPowersOf2(int n) {
if (n >= 0 && n <= 64) {
for (int i = 0 ; i <= n ; i++) {
System.out.print( Math.pow(2, i) + " ");
}
} else {
System.out.println("You have input an invalid value");
return;
}
}
public static void main(String[] args) {
printPowersOf2(31);
System.out.println();
}
}
However, it produces the following result instead:
1.0 2.0 4.0 8.0 16.0 32.0 64.0 128.0 256.0 512.0
1024.0 2048.0 4096.0 8192.0 16384.0 32768.0 65536.0
131072.0 262144.0 524288.0 1048576.0 2097152.0 4194304.0
8388608.0 1.6777216E7 3.3554432E7 6.7108864E7 1.34217728E8
2.68435456E8 5.36870912E8 1.073741824E9 2.147483648E9
How can I fix that?
Also I have another question
When I input larger values for n such as 62 the values start to be the same. For example 62 gives:
1 2 4 8 16 32 64 128 256 512 1024 2048 4096
8192 16384 32768 65536 131072 262144 524288 1048576
2097152 4194304 8388608 16777216 33554432 67108864 134217728
268435456 536870912 1073741824 2147483647 2147483647
2147483647 2147483647 2147483647 2147483647 2147483647
2147483647 2147483647 2147483647 2147483647 2147483647
2147483647 2147483647 2147483647 2147483647 2147483647
2147483647 2147483647 2147483647 2147483647 2147483647
2147483647 2147483647 2147483647 2147483647 2147483647
2147483647 2147483647 2147483647 2147483647 2147483647
how can I fix this issue?
Since Math.pow returns a double while you are looking for an integer, consider using a simple bit trick for raising 2 to power n like this:
1L << n
The reason behind this trick is the same as that behind multiplying by powers of ten in the decimal system by writing additional zeros after the number.
This works for ns between 0 and 63, and produce a long:
for (int i = 0 ; i <= n ; i++) {
System.out.print( (1L << i) + " ");
}
Math.pow() always returns doubles. You need to cast it to an int. System.out.print((int)Math.pow(2, i)+ " ");
Because public static double pow(double a, double b) return a double. And Java double is 64 bit IEE754 number with precision, so you see the decimal points in the end.
You can cast it to int as (int)Math.pow(2, i)but be aware that for 2^31 onwards you will not get expected results because int range is from -2^31 to +2^31.
** First Solution:**
So, to get your expected result to get power up to 63, cast to long because Java long has range from -2^63 to +2^63
for (int i = 0; i <= 64; i++) {
System.out.println((long)Math.pow(2, i));
}
You query about result as so many 2147483647 :
This is called as Narrowing, when a bigger container value is casted to smaller container value.
Below excerpt from Java Language Specification - $5.1.3 Narrowing Primitive Conversion, for rules governing primitive narrowing.
So, after power of 31, all the higher bits (32, 33....) are discarded, and hence you always result of 31 bits i.e. 2^31.
In you case, as per JLS, your "integral type T" was int, so all bits are discarded but the n lowest order bits (which means 31, because you are narrowing to int)
A narrowing conversion of a signed integer to an integral type T
simply discards all but the n lowest order bits, where n is the number
of bits used to represent type T. In addition to a possible loss of
information about the magnitude of the numeric value, this may cause
the sign of the resulting value to differ from the sign of the input
value.
A comprehensive solution: (as per discussion going around)
Primitive data types has range limitation, so there are BigInteger, BigDecimal which provides arbitrarily long values and precision. So, you can use BigInteger to get accurate result.
Notice that if you Java's long then for 2^63 you get result as 9223372036854775807 while as per Power of two Wiki result should be 9223372036854775808 which you get when you use BigInteger
Bottom line: Use BigInteger to get desired range of power of 2.
Hope this covers all your concern and give you scalable solution.
for (int i = 0; i <= 64; i++) {
//System.out.println((long)Math.pow(2, i));
System.out.println(BigInteger.valueOf(2).pow(i)); //Gives exact result as per Wiki information
}
These are the powers of 2 through 2^31, just in the default output format of a double. With lower values, it will append .0, and with higher values, it's in pseudo-scientific notation. E.g. 1.6777216E7 means 1.677216 x 107, or 1,677,216. The double is returned from Math.pow.
You may find an integer type data type better formatted for your purpose. Use long, because int isn't quite big enough to store 2^31.
long product = 1;
for (int i = 0 ; i <= n ; i++)
{
System.out.print( product + " ");
product *= 2; // Equivalent: product <<= 1;
}
i could have used below code part, instead math.pow() , i am always scared of type conversion
int num=1;
for(int i=0;i<n;i++){
System.out.println(num);
num=num*2;
}
but as suggested it can not go beyond 31 . it is limit of int data type. try BigInteger if you want to print more
With Java 8 you can simply use the following stream:
IntStream.range(0, 32)
.map(value -> 1 << value)
.forEach(value -> System.out.println("value = " + value));
Also, the same is applicable to LongStream.

How Java processes for overflow integers [duplicate]

This question already has answers here:
Why do these two multiplication operations give different results?
(2 answers)
Closed 9 years ago.
Now signed_int max value is 2,147,483,647 i.e. 2^31 and 1 bit is sign bit, so
when I run long a = 2,147,483,647 + 1;
It gives a = -2,147,483,648 as answer.. This hold good.
But, 24*60*60*1000*1000 = 86400000000 (actually)...
In java, 24*60*60*1000*1000 it equals to 500654080..
I understand that it is because of overflow in integer, but what processing made this value come, What logic was used to get that number by Java. I also refered here.
Multiplication is executed from left to right like this
int x = 24 * 60;
x = x * 60;
x = x * 1000;
x = x * 1000;
first 3 operations produce 86400000 which still fits into Integer.MAX_VALUE. But the last operation produces 86400000000 which is 0x141dd76000 in hex. Bytes above 4 are truncated and we get 0x1dd76000. If we print it
System.out.println(0x1dd76000);
the result will be
500654080
This is quite subtle: when writing long a = 2147483647 + 1, the right hand side is computed first using ints since you have supplied int literals. But that will clock round to a negative (due to overflow) before being converted to a long. So the promotion from int to long is too late for you.
To circumvent this behaviour, you need to promote at least one of the arguments to a long literal by suffixing an L.
This applies to all arithmetic operations using literals (i.e. also your multiplication): you need to promote one of them to a long type.
The fact that your multiplication answer is 500654080 can be seen by looking at
long n = 24L*60*60*1000*1000;
long m = n % 4294967296L; /* % is extracting the int part so m is 500654080
n.b. 4294967296L is 2^32 (using OP notation, not XOR). */
What's happening here is that you are going 'round and round the clock' with the int type. Yes, you are losing the carry bits but that doesn't matter with multiplication.
As the range of int is -2,147,483,648 to 2,147,483,647.
So, when you keep on adding numbers and its exceed the maximum limit it start gain from the left most number i.e. -2,147,483,648, as it works as a cycle. That you had already mentioned in your question.
Similarly when you are computing 24*60*60*1000*1000 which should result 86400000000 as per Maths.
But actually what happens is somehow as follows:
86400000000 can be written as 2147483647+2147483647+2147483647+2147483647+..36 times+500654080
So, after adding 2147483647 for 40 times results 0 and then 500654080 is left which ultimately results in 500654080.
I hope its clear to you.
Add L in your multiplicatoin. If you add L than it multiply you in Long range otherwise in Integer range which overflow. Try to multiply like this.
24L*60*60*1000*1000
This give you a right answer.
An Integer is 32 bit long. Lets take for example a number that is 4 bit long for the sake of simplicity.
It's max positive value would be:
0111 = 7 (first bit is for sign; 0 means positive, 1 means negative)
0000 = 0
It's min negative value would be:
1111 = -8 (first bit is for sign)
1000 = -1
Now, if we call this type fbit, fbit_max is equal to 7.
fbit_max + 1 = -8
because bitwise 0111 + 1 = 1111
Therefore, the span of fbit_min to fbit_max is 16. From -8 to 7.
If you would multiply something like 7*10 and store it in fbit, the result would be:
fbit number = 7 * 10 (actually 70)
fbit number = 7 (to get to from zero to max) + 16 (min to max) + 16 (min to max) + 16 (min to max) + 15 (the rest)
fbit number = 6
24*60*60*1000*1000 = 86400000000
Using MOD as follows: 86400000000 % 2147483648 = 500654080

Casting long to byte in Java

I am unable to understand the following:
In java,
long l = 130L;
byte b = (byte)l;
If I print the value of b, why do I get -126? What is the bit representation of long l?
A byte is a sequence of 8 bits, which makes 2^8 cases = 256. Half of them represent negative numbers, which is -128 to -1. Then there is the 0, and about the half, 1 to 127 represent the positive numbers.
130 as Int looks like 128 + 2 which is:
0000:0000 1000:0000 (128)
0000:0000 0000:0010 (2)
0000:0000 1000:0010 (130)
However, the Byte has just 8 digits, and the assignment takes just the bits as they are, but just the last ones:
1000:0010
The first bit indicates, it is a negative number. Now how much do you need to add to get to zero? Let's do it stepwise:
1000:0010 x +
0000:0001 1 =
----------------
1000:0011 (x+1)
1000:0011 (x+1) +
0000:0001 1 =
----------------
1000:0100 (x+2)
Lets do bigger steps. Just add 1s where we have zeros, but first we go back to x:
1000:0010 x +
0111:1101 y =
--------------
1111:1111
Now there is the turning point: we add another 1, and get zero (plus overflow)
1111:1111 (x + y) +
0000:0001 1
---------
0000:0000 0
If (x+y) + 1 = 0, x+y = -1. A minus 1 is, interestingly, not just the same as 1 (0000:0001) with a 'negative-flag' set ('1000:0001'), but looks completely different. However, the first position always tells you the sign: 1 always indicates negative.
But what did we add before?
0111:1101 y = ?
It doesn't have a 1 at the first position, so it is a positive value. We know how to deconstruct that?
..f:8421 Position of value (1, 2, 4, 8, 16=f, 32, 64 in opposite direction)
0111:1101 y = ?
..f 84 1 = 1+4+8+16+32+64= 125
And now it's clear: x+125 = -1 => x = -126
You may imagine the values, organized in a circle, with the 0 at the top (high noon) and positive values arranged like on a clock from 0 to 5 (but to 127), and the turning point at the bottom (127 + 1 => -128 [sic!].) Now you can go on clockwise, adding 1 leads to -127, -126, -125, ... -3, -2, -1 (at 11 o'clock) and finally 0 at the top again.
For bigger numbers (small, int, long) take bigger clocks, with the zero always on top, the maximum and minimum always on bottom. But even a byte is much too big, to make a picture, so I made one of a nibble, a half-byte:
You can easily fill the holes in the picture, it's trivial!
Btw.: the whole thing isn't called casting. Casting is only used between Objects. If you have something, which is in real a subtype:
Object o = new String ("casting or not?");
this is just an assignment, since a String is (always) an Object. No casting involved.
String s = (String) o;
This is a casting. To the more specific type. Not every object is a String. There is a small relationship to integer promotion, since every byte can be lossless transformed to long, but not every long to byte. However, even Byte and Long, the Object-types, aren't inherited from each other.
You just don't get a warning, for
byte s = (byte) 42;
long o = s; // no problem, no warning
byte b = (byte) o; // written like casting
Bytes are signed in Java - so the range of values is -128 to 127 inclusive.
The bit pattern for 130 as a long, when simply truncated to 8 bits, is the bit pattern for -126 as a byte.
As another example:
int x = 255;
byte b = (byte) x; // b is now -1
You mean byte b = (byte)l?
Java's types are signed, so bytes allow numbers between -128 and +127.
For beginners to understand:
1 byte = 8 bits
Range (derived from 2's complement no. system) = [-2^(n-1) to 2^(n-1)-1], where n is no. of bits
So range is -128 to 127
Whenever value is incremented more than highest possible +ve value, the flow goes to the lowest possible -ve value.
So after value reaches 127 , flow continues from -128 to -127 to -126
to cover a total space of 130 and the thus o/p is -126

Categories