why this would result in long integer overflow

前端 未结 5 1198
执念已碎
执念已碎 2021-02-18 18:45

I checked the document that long= int64 has range more than 900,000,000,000,000

Here is my code:

int r = 99;
long test1 = r*r*r         


        
相关标签:
5条回答
  • 2021-02-18 19:04

    It's using integer multiplication :

    long r = 99;
    long test1 = r*r*r*r*r;
    
    0 讨论(0)
  • 2021-02-18 19:07

    The compiler is looking at 99 as integers, even though the final result will be long.

    This will work.

    long test2 = 99L*99L*99L*99L*99L;
    
    0 讨论(0)
  • 2021-02-18 19:11

    The problem is that the literal "99" is being treated as an int. If you add "L" it will treat it as a long. To fix your compilation problem:

    long test2 = 99L * 99L * 99L * 99L * 99L;
    

    And to fix the "incorrect result" caused by integer overflow:

    long r = 99;
    long test1 = r * r * r * r * r;
    

    The key point is that the expression to the right of the "=" is evaluated before the assignment to long r is done.

    There are other literal suffixes you might be interested in:

    Type    Suffix    Example
    uint    U or u    100U
    long    L or l    100L
    ulong   UL or ul  100UL
    float   F or f    123.45F
    decimal M or m    123.45M
    

    @m.edmonson, regarding your question about why it comes out to 919965907. What's happening, is that the value is "wrapping" around int.MaxValue. You can see this with a little test program:

    int i = 99; // 99
    i *= 99;    // 9801
    i *= 99;    // 970299
    i *= 99;    // 96059601
    i *= 99;    // 919965907        should be 9509900499 but comes out to 919965907
                //                      which is (9509900499 % int.MaxValue)
    
    long k = 9509900499 % int.MaxValue;
    

    What is meant by "wrapping around"? When you exceed int.MaxValue by 1, the value "goes back" to int.MinValue.

    int j = int.MaxValue;
    j++;
    
    bool isNowMinValue = (j == int.MinValue);   // true, the value has "wrapped around"
    

    This is a bit simplistic; if you search for "integer overflow" you will get a better explanation. It's worth understanding how integers (and other numeric types) are represented with 32 bits:

    http://en.wikipedia.org/wiki/Signed_number_representations

    0 讨论(0)
  • 2021-02-18 19:14

    Your second test fails because each 99 is an integer; replace it with the following and it compiles.

    long test2 = 99L * 99L * 99L * 99L * 99L;
    

    See the MSDN Long Documentation for details.

    0 讨论(0)
  • 2021-02-18 19:18

    As the other have said, but:

    long test2 = 99L * 99 * 99 * 99 * 99;
    

    This will give you the correct result with less L around :-)

    This happens because the first 99L is a long, so all the multiplications are done in the long "field" and all the other integers are upcasted to long before the multiplication (clearly the multiplication is always between 2 numbers and it's from left to right, so it's like (((99L * 99) * 99) * 99) * 99 and each "partial" result is a long and causes the next operand to be converted to long.)

    0 讨论(0)
提交回复
热议问题