5

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

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

4

3 回答 3

16

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

考虑:

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

原因是负整数1在最大位用a表示,所以任何大于最大值的乘法都会1在这个位置有a,这被解释为负值。

溢出对于所有整数类型(intshortbytesbytecharlongulongushortuint)都是一种危险。您可以使用浮点类型,例如floator double,但这会带来其他问题,例如舍入和相等问题。您必须知道您期望什么样的数字,然后您可能会使用其他类型,如,long或浮点类型,如or 。最终,如果您不知道会发生什么,您需要在输入上编写保护代码(例如将其包装在一个块中[thanks, @EricLippert],并在它的值超出您的范围时进行处理专为。uintulongdoubledecimalchecked { }

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

于 2013-03-09T20:14:49.583 回答
3

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

编辑:没有必要使用BigInteger这种情况,因为int x int永远不会溢出long.

于 2013-03-09T20:17:18.110 回答
0

它可能是整数溢出异常。即使您将数字存储在足够大的变量中,它也可能发生。示例(长,双等)

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 
于 2016-06-25T15:51:11.433 回答