2012-10-02 64 views
3

我有代码,设置的小区的默认值到单元格的值以上乘以100:为什么10亿* 100 == 12亿?

const int DUCKBILL_MULTIPLIER = 100; 
. . . 
cellValue = dataGridViewPlatypi.Rows[args.RowIndex - 1].Cells[0].Value; 
if (Convert.ToInt32(cellValue) > 0) 
{ 
    int nextDefaultVal = Convert.ToInt32(cellValue) * DUCKBILL_MULTIPLIER; 
    cellValue = nextDefaultVal; 
} 
prevVal = cellValue == null ? string.Empty : cellValue.ToString(); 
. . . 
dataGridViewPlatypi.Rows[args.RowIndex].Cells[args.ColumnIndex].Value = prevVal; 

但是,一旦上述值上是十亿(1十亿)时,下一个值是1215752192 (1,215,752,192或约12亿美元)而不是1,000亿美元。我知道最大整数值是2,147,483,647(约21亿);我知道最大整数值是2,147,483,647(约21亿);我知道最大整数值是2,147,483,647(约21亿)。那么为什么下一个值是1,215,752,192而不是2,147,483,647?

顺便说一句,这些vals大于应用程序将需要,但我发现这在测试“极端”的情况下。

+10

整数溢出...整数不饱和。他们翻身。 – Mysticial

回答

16

因为多个溢出正在发生。每次达到2,147,483,647时,计数都会重新开始。现在,你必须记住它溢出到-2,147,483,648。因此,我们必须考虑到整体的Int32范围,这是4,294,967,296(也可以从(Int64)Int32.MaxValue + 1 - Int32.MinValue或者干脆2^32计算

数学:

(1 billion * 100) % (4,294,967,296) = 1215752192 

在C#代码的概念证明:

var range = (Int64)Int32.MaxValue + 1 - Int32.MinValue; 
Int64 val = 100000000000 % range; 
Console.WriteLine(range); 
Console.WriteLine(val); 
+0

您的意思是'%2,147,483,648',因为(10亿* 100)%2147483648是1215752192,这是问题中报告的值。 – phoog

+0

@phoog注意,只是更新了答案 –

+1

当数字溢出时,它会溢出到'-2,147,483,648',而不是'0'。你需要采用'4294967296'(2^32)的mod,在这种情况下仍然给出相同的答案。 – Servy