The numbers are probably large enough to overflow Int32.MaxValue
.
Consider:
var r = Int32.MaxValue / 2; // r = 1073741823
var ans = r * 3; // ans = -1073741827
The reason for this is that negative integers are represented with a 1
in the largest bit, so any multiplication which is larger than the maximum value will have a 1
in this position, which is interpreted as a negative value.
Overflow is a danger with all integral types (int
, short
, byte
, sbyte
, char
, long
, ulong
, ushort
, and uint
). You could use a floating point type, like float
or double
, but this comes with other problems, like rounding and equality issues. You have to know what kind of numbers you expect, then you might use other types like long
, uint
, ulong
or a floating point type like double
or decimal
. Ultimately, if you don't know what could happen, you need to write guard code on the input (e.g. wrap it in a checked { }
block [thanks, @EricLippert]), and handle it when it is a value outside the range you've designed for.
EDIT: Another option in .Net 4.0+ is to use System.Numerics.BigInteger
, which avoids any overflow, but can be slow.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…