问题描述
我收到此错误: System.OverflowException: '值不是数字。' 我的印象是大整数可以存储任何大小的值(在这种情况下为 500 ^ 500),所以我不明白为什么会发生这种情况。
public int decode(int code)
{
int totient = (p - 1) * (q - 1);
int d = modInverse(e,totient);
int pq = p * q;
BigInteger decodedMessage = new BigInteger(Math.Pow(code,d) % pq);
return (int)decodedMessage;
}
解决方法
BigInteger decodedMessage = new BigInteger(Math.Pow(code,d) % pq);
好吧,Math.Pow(code,d) % pq
不是 BigInteger,它是 double
类型的表达式。在计算完成(并溢出)之前,将 result 转换为 BigInteger 不会产生任何影响。
Math.Pow
很容易溢出到 Double.PositiveInfinity
的大数,而 Double.PositiveInfinity % someNumber
产生 Double.NaN
。调用 new BigInteger(Double.NaN)
会产生您所描述的错误。
您需要在 BigInteger 中进行计算。幸运的是,有一种方法可以达到这个目的 (BigInteger.ModPow):
BigInteger decodedMessage = BigInteger.ModPow(code,d,pq);
(BigInteger.ModPow 需要 BigInteger 参数,但存在从 int 到 BigInteger 的隐式转换。)
,看来pq
是0
,接下来抛出同样的异常:
new BigInteger(0.0 % 0);
double
除以零导致 Double.NaN
根据 docs 这不是实例化 BigInteger
的有效值:
异常
溢出异常
value
是 NaN、NegativeInfinity 或 PositiveInfinity。
或者,正如注释中正确提到的 @Heinzi Math.Pow
导致 Infinity。