Wonder why. C# .Net 3.5
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * a;
Console.WriteLine(c);//<-- result is -2147483648
Where does this minus from?
Wonder why. C# .Net 3.5
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * a;
Console.WriteLine(c);//<-- result is -2147483648
Where does this minus from?
Where does this minus from?
From the integer overflow. Note that your code is equivalent to:
int a = 256 * 1024 * 1024;
int b = 8;
int tmp = b * a;
long c = tmp;
Console.WriteLine(c);
I've separated out the multiplication from the assignment to the long
variable to emphasize that they really are separate operations - the multiplication is performed using Int32
arithmetic, because both operands are Int32
- the fact that the result is assigned to an Int64
afterwards is irrelevant.
If you want to perform the multiplication in 64-bit arithmetic, you should cast one of the operands to long
(i.e. Int64
):
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * (long) a;
Console.WriteLine(c); // 2147483648
(It doesn't matter which operand you cast to long
- the other one will be implicitly converted to long
anyway.)
int
is a 32 bit signed value type, wich means the very last bit is used to specify if the number is positive or negative.
int
value ranges from -2147483648
to 2147483647
. This is
1000 0000 0000 0000 0000 0000 0000 0000
to
0111 1111 1111 1111 1111 1111 1111 1111
in binary. Now:
256 * 1024 * 1024
equals 268435456
or
0001 0000 0000 0000 0000 0000 0000 0000
binary.
268435456 * 8
equals 2147483648
or
1000 0000 0000 0000 0000 0000 0000 0000
.
As the value is still an int
, this loops back to the max negative number because, as stated, the last bit is used to specify if the number is positive or negative. So, 2147483648
is turned into -2147483648
The maximum value that int
supports is 2147483647
. The expected result 2147483648
does not fit in this type range, hence an overflow occurs causing the result to be negative.
Note that the statement long c = b * a;
translates to the following two steps:
Multiple the int
values of b
and a
. The int
result is negative due to integer overflow.
Convert the already negative result to long
.
Try casting to long
before multiplying:
long c = b * (long) a;
or declare a
be of type long
:
long a = 256L * 1024L * 1024L;
As was stated by others, you should have one of the operands in expression as long
to yield long
, but in your case all operands are int
and therefore, int
is returned.
You should cast one of them to long:
int a = 256 * 1024 * 1024;
int b = 8;
long c = (long)b * a;
The same happens when you divide:
int a=1, b=2;
float c = a / b; //results in 0
So cast one of operands to the resulting type:
int a=1, b=2;
float c = (float)a / b; //results in 0.5
BTW, there is also C# directive for checking arithmetic overflow: checked
keyword
checked
{
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * a; //this will throw System.OverflowException
}
It cast the result to long not the operation, if one of the operands is long it works This works fine:
long a = 256L * 1024L * 1024L;
int b = 8;
long c = b * a;
Console.WriteLine(c);
as does this:
int a = 256 * 1024 * 1024;
long b = 8L;
long c = b * a;
Console.WriteLine(c);
and this (only one of the two needs to be cast but I did both to be clear):
int a = 256 * 1024 * 1024;
int b = 8;
long c = (long)b * (long)a;
Console.WriteLine(c);
Because b * a is already overflowed integer, before it is assigned to the long data type variable.
© 2022 - 2024 — McMap. All rights reserved.