Mulitplying Large Int64 numbers

When multiplying very large Int64 numbers, I've noticed some strange results.

For example, in C# .NET:
   Int64 lngNumber;
   lngNumber = 4611686018427387904;
   lngNumber = lngNumber*2;
   Console.WriteLine(lngNumber.ToString());
Outputs    -9223372036854775808

Changing the multiplier to 3 as follows:
   Int64
lngNumber;
   lngNumber = 4611686018427387904;
   lngNumber = lngNumber*2;
   Console.WriteLine(lngNumber.ToString());

Gives    -4611686018427387904

Changing the multiplier to 4 as follows:
   Int64 lngNumber;
   lngNumber = 4611686018427387904;
   lngNumber = lngNumber*4;
   Console.WriteLine(lngNumber.ToString());
Outputs    
0 (but no exception)

Making the lngNumber slightly lower, gives a different effect.
A valid calculation works fine:
Int64 lngNumber = 4611686018427387000;
lngNumber = lngNumber*2;
Console.WriteLine(lngNumber.ToString());


This correctly returns 
9223372036854774000
Whereas multiplying it by 3 returns -4611686018427390616.
Multiplying by 4 returns -3616.
By 5 returns 4611686018427383384.
By 6 returns 9223372036854770384.
By 7 returns -4611686018427394232.
By 8 returns -7232.

It seems to be looping round - once it reaches the maximum number allowed for an Int64, it keeps adding on at -9223372036854775808.

Has anyone any idea why this happens
Is it an error
I've been told that there is no exception raised for overflowing an integer in C, C++ and C#.  Why not   And why would it return an incorrect value

Surely it would be better to return an exception like an overflow to a Byte or smaller integer does.  I think that the Int64 struct should test the value being assigned to it, and reject it if it cannot handle it.



Answer this question

Mulitplying Large Int64 numbers

  • vignali

    This looping around happens because of binary logic. You have exceeded the max positive value for the Int64 which is (2^63 - 1). When this happens, the 64th bit may be 1 or 0 depending on the calculation result. When this bit is a 1 the value will appear to be negative. When it is 0 the value will appear to be positive.

    My assumption why checking arithmetic for integer overflowing is not implemented is because it is not worth the performance decrease.

    You can probably produce similar effects with an Int and Short.

    This is expected behavior and is not an error.


  • Nicholas Marston

    Use   checked   compiler option, context or operator to throw System.OverflowException in case of overflows.

    checked {
       Int64 lngNumber;
       lngNumber = 4611686018427387904;
       lngNumber = lngNumber*2;

    }

    or 

      Int64 lngNumber;
      lngNumber = 4611686018427387904;
      lngNumber = checked( lngNumber*2 );

  • Mulitplying Large Int64 numbers