Multiplying int with long result c#
Asked Answered
F

6

8

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?

Fake answered 26/1, 2015 at 17:36 Comment(0)
P
13

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.)

Propagable answered 26/1, 2015 at 17:39 Comment(1)
I'd been confused by the value of result which is the same as expected but with negative sign. If i would used other values it would be much clearer that is an overflow problem.Bretbretagne
O
2

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

Ollieollis answered 26/1, 2015 at 17:48 Comment(0)
C
1

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:

  1. Multiple the int values of b and a. The int result is negative due to integer overflow.

  2. 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;
Chitarrone answered 26/1, 2015 at 17:40 Comment(0)
B
1

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
}
Barratry answered 26/1, 2015 at 17:52 Comment(0)
B
0

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);
Burdensome answered 26/1, 2015 at 17:40 Comment(0)
V
0

Because b * a is already overflowed integer, before it is assigned to the long data type variable.

Vial answered 26/1, 2015 at 17:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.