将两个正数Int32相乘将返回不正确的负数答案

本文关键字:返回 不正确 答案 Int32 两个 | 更新日期: 2023-09-27 18:03:13

我真的被这个问题难住了。我正在为Windows Phone 7.5编写c#代码;我从文本框中获取文本,将其解析为数组,然后使用Convert将每个数组元素转换为Int32。ToInt32,然后通过一系列数学计算运行结果Int32值,将Int32值乘以硬编码的数字(所有这些都取决于UI中选择的内容)。

一切都很好,直到我把结果计算并将它们相乘:我从两个正数相乘得到一个负数!这是我唯一一次对使用Convert的方法中产生的两个数字进行任何计算。ToInt32函数。当它们相加,减法,甚至除法时,数学结果是正确的。但是当它们相乘时,没有骰子。数学是完全错误的;我仔细检查了一下LibreOffice Calc中的数学,结果不匹配。在逐步执行代码时,在使用Convert的方法中产生的数字之前,一切都是正确的。ToInt32函数相乘。什么好主意吗?

将两个正数Int32相乘将返回不正确的负数答案

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

考虑:

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

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

溢出对于所有整型(int, short, byte, sbyte, char, long, ulong, ushortuint)都是危险的。您可以使用浮点类型,如floatdouble,但这会带来其他问题,如舍入和等问题。你必须知道你想要什么样的数字,然后你可以使用其他类型,如long, uint, ulong或浮点类型,如doubledecimal。最后,如果您不知道可能发生什么,则需要在输入上编写保护代码(例如:将其包装在checked { }[thanks, @EricLippert])中,并在它是超出您设计范围的值时处理它。

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

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

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

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

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