乘以两个正Int32返回错误的否定答案?

我真的很难过这个。 我正在使用C#编写Windows Phone 7.5; 我从文本框中取出文本,将其解析为数组,然后使用Convert.ToInt32将每个数组元素转换为Int32,然后通过一系列数学计算运行生成的Int32值,将Int32值乘以并添加到硬编码数字(均取决于UI中选择的内容)。

一切都很好,直到我得到结果计算并将它们相乘:我从两个正数乘以得到一个负数! 这是我唯一一次使用源自使用Convert.ToInt32函数的方法的数字进行任何计算。 当它们被加,减,甚至分开时,数学运算正确。 但是当它们成倍增长时,没有骰子。 数学是完全错误的; 我仔细检查了LibreOffice Calc中的数学并且它不匹配。 当单步执行代码时,一切都是正确的,直到源自使用Convert.ToInt32函数的方法中的数字相乘。 有任何想法吗?

这些数字可能足以溢出Int32.MaxValue

考虑:

 var r = Int32.MaxValue / 2; // r = 1073741823 var ans = r * 3; // ans = -1073741827 

其原因是负整数在最大位中用1表示,因此任何大于最大值的乘法在该位置将具有1 ,这被解释为负值。

溢出是所有整数类型( intshortbytesbytecharlongulongushortuint )的危险。 您可以使用浮点类型,例如floatdouble ,但这会带来其他问题,例如舍入和平等问题。 您必须知道您期望的数字类型,然后您可以使用其他类型,如longuintulong或浮点类型,如doubledecimal 。 最后,如果您不知道会发生什么,您需要在输入上编写保护代码(例如将其包装在已checked { }[thanks,@ EricLippert]中 ,并在超出范围的值时处理它你为之设计的。

编辑:.Net 4.0+中的另一个选项是使用System.Numerics.BigInteger ,它可以避免任何溢出,但可能很慢。

快速而肮脏的解决方案就是将其中一个值转换为long ,然后将结果转换回int ,如果可能的话。

编辑:在这种情况下不需要使用BigInteger ,因为int x int永远不会溢出long

它可能是一个Integer溢出exception。 即使您将数字存储在足够大的变量中,也可能发生这种情况。 示例(长,双等)

 int one = int.MaxValue; int two = int.MaxValue; long sum = (long)(one + two); //Returns -2, because the cast was after the sum //(long) -2. 

您可以在总和之前投射它们并获得正确的结果

 int one = int.MaxValue; int two = int.MaxValue; long sum = (long) one + (long)two; //Returns 4294967294, it casts both the //integer to long and then adds them