将两个正数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.MaxValue
考虑:
var r = Int32.MaxValue / 2; // r = 1073741823
var ans = r * 3; // ans = -1073741827
这样做的原因是负整数在最大位上用1
表示,因此任何大于最大值的乘法都会在这个位置上有一个1
,这被解释为一个负值。
溢出对于所有整型(int
, short
, byte
, sbyte
, char
, long
, ulong
, ushort
和uint
)都是危险的。您可以使用浮点类型,如float
或double
,但这会带来其他问题,如舍入和等问题。你必须知道你想要什么样的数字,然后你可以使用其他类型,如long
, uint
, ulong
或浮点类型,如double
或decimal
。最后,如果您不知道可能发生什么,则需要在输入上编写保护代码(例如:将其包装在checked { }
块[thanks, @EricLippert])中,并在它是超出您设计范围的值时处理它。
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