为什么我使用大整数 (System.Numerics) 会导致系统溢出?

Why am I getting a system overflow using big integer (System.Numerics)?

我收到此错误:System.OverflowException:'The value is not a number.' 我的印象是大整数可以存储任何大小的值(在这种情况下为 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;
}

好像pq0,next抛出同样的异常:

new BigInteger(0.0 % 0);

double 除以零导致 Double.NaN 根据 docs:

这不是实例化 BigInteger 的有效值

Exceptions

OverflowException

value is NaN, NegativeInfinity, or PositiveInfinity.

或者,正如 @Heinzi 在评论中正确提到的 Math.Pow 结果是 Infinity。

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 的隐式转换。)