我真的难倒就这一个。 我编码在C#中的Windows Phone 7.5; 我正在文本从一个文本框,它解析成一个阵列,然后使用Convert.ToInt32每个阵元变换成一个Int32,然后通过一系列数学计算的运行所产生的Int32值,相乘并添加Int32值到硬编码号码(全部取决于什么在UI中选择'S)。
一切都很好,直到我承担由此产生的计算和一起乘他们:我得到一个负数繁殖的两个正数! 这是我做的任何计算既起源于一个使用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 { }
块[感谢,@EricLippert]),并处理它时,它是在范围之外的值你设计的。
编辑:在.net 4.0以上版本的另一种选择是使用System.Numerics.BigInteger
,避免任何溢出,但可能会很慢。
快速和肮脏的解决方案只是施放的一个值的long
,然后把结果返回int
,如果可能的话。
编辑:有没有必要使用BigInteger
这种情况下, int x int
不能溢出long
。
它可能是一个整数溢出异常。 即使你是存放在变量是足够大的数量,可以发生。 实施例(长,双等)
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