Multiplying int with long result c#

后端 未结 6 1584
自闭症患者
自闭症患者 2020-12-18 07:29

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 do

相关标签:
6条回答
  • 2020-12-18 07:44

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

    0 讨论(0)
  • 2020-12-18 07:45

    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

    0 讨论(0)
  • 2020-12-18 07:46

    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);
    
    0 讨论(0)
  • 2020-12-18 07:48

    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
    }
    
    0 讨论(0)
  • 2020-12-18 07:59

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

    0 讨论(0)
  • 2020-12-18 08:03

    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;
    
    0 讨论(0)
提交回复
热议问题