非常大的长型号变为负数

时间:2016-11-15 03:29:59

标签: c#

目前,我的C#代码存在一些问题。我有一组代码应该以“x ^ y ^ z ...”的形式将字符串转换为数字,所以我设置了一个看起来像这样的方法。

public long valueOfPower()
{
    long[] number = Array.ConvertAll(this.power.Split('^'), long.Parse);
    if(number.Length == 1)
    {
        return number[0];
    }
    long result = number[0];
    long power = number[number.Length-1];
    for (long i = number.Length-1; i > 1; i-- )
    {
        power = (long)Math.Pow((int)number[(int)i-1], (int)power);
    }
    result= (long)Math.Pow((int)result,(int)power);
    return result;
}

我遇到的问题是当输入2 ^ 2 ^ 2 ^ 2 ^ 2之类的东西时,我得到一个非常大的负数。我不确定我的代码是否有问题,或者因为2 ^ 2 ^ 2 ^ 2 ^ 2对于长对象来说太大了,但是我不明白发生了什么。

所以,问题是,当“this.power”为2 ^ 2 ^ 2 ^ 2 ^ 2时,为什么我的代码返回一个大的负数,而输入较小的正常数字(如2 ^ 2 ^ 2 ^ 2) )? (对不起随机演员,我来自于试验不同的数字类型。)

3 个答案:

答案 0 :(得分:5)

发生的事情是溢出。每种数据类型都存储为一定数量的位。由于该位数有限,因此任何数据类型可以存储的最大数量是有限的。因为最重要的位通常代表数字的符号,所以当超过数据类型的最大值时,该位将翻转,计算机现在将其解释为负数。

如果数学会溢出,您可以使用checked关键字抛出异常。有关详细信息,请访问:https://msdn.microsoft.com/en-us/library/74b4xzyw.aspx

另一种可能的解决方案是使用BigInteger。更多信息:https://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx

请参阅此处了解C#中数据类型的最大值:http://timtrott.co.uk/data-types-ranges/

有关溢出的更多信息,请参阅此处:https://en.wikipedia.org/wiki/Integer_overflow

答案 1 :(得分:0)

2^2^2^2^2quite a large number,结果是溢出了长数据类型(9,223,372,036,854,775,807)的最大长度但是有一些余量。

您可以尝试使用System.Numerics中的BigInteger类,或者提出一些其他方法来表示这样的数字。

答案 2 :(得分:0)

您遇到的溢出问题是因为您正在进行预测。

数字和功率应该是long,但在你的计算中,例如:

power = (long)Math.Pow((int)number[(int)i-1], (int)power);
// you are downcasting number and power into int.

int进行计算时,由于溢出,您的值将变为负值,然后将其转换回long

此外,我的Math.Pow仅接受double作为参数并返回double。我不知道如何允许您提供int作为参数。

因此,要解决您的问题,它应该如下所示:

power = (long)Math.Pow((double)number[(int)i-1], (double)power);
// and
result= (long)Math.Pow((double)result,(double)power);

然后,如果您想获得大于long的内容,请考虑使用BigInteger