You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用System.Numerics的BigInteger计算时为何触发系统溢出异常?

报错核心成因

你之前的认知是对的:BigInteger本身完全可以无精度损失地存储、计算任意大小的整数,包括你提到的500^500。这次报错和BigInteger的存储能力没有任何关系,问题出在代码的运算流程上:

  • 你在代码中根本没有让BigInteger参与幂运算,反而先调用了Math.Pow(code, d):这个方法的输入输出都是双精度浮点数(double),不是为整数大数值运算设计的。
  • 计算500^500这类量级的结果时,数值远远超出double的可表示范围,Math.Pow会直接返回NaN(非数字值),把这个无效的非数字值传给BigInteger的构造函数时,就触发了System.OverflowException: 'The value is not a number.'。

同时你的RSA实现还存在两个长期隐患:

  • 全程用int类型存储totient、d、pq这类核心密钥参数,这类参数在实际使用中很容易超出int的取值范围,哪怕解决了当前的报错,后续也会频繁触发int溢出问题。
  • 直接计算完整的code^d再取模的方式效率极低,对于大幂次计算会生成远超内存承载能力的超大整数,甚至直接卡死程序。
修复方案
  • 把所有参与RSA计算的密钥、密文、中间值全部替换为BigInteger类型,从根源上规避int溢出、浮点精度丢失的问题。
  • 弃用Math.Pow这类浮点运算方法,直接使用BigInteger原生的ModPow方法完成RSA要求的幂模计算,既可以避免浮点误差,也能通过内置的快速幂算法大幅提升大幂次的计算效率。
  • 你原本实现的modInverse方法也要同步改造为支持BigInteger类型的入参和返回值,保证模逆运算的正确性。

参考修正后的代码逻辑:

public int decode(int code)
{
    BigInteger bigP = new BigInteger(p);
    BigInteger bigQ = new BigInteger(q);
    BigInteger bigE = new BigInteger(e);
    
    BigInteger totient = (bigP - 1) * (bigQ - 1);
    BigInteger d = ModInverse(bigE, totient);
    BigInteger pq = bigP * bigQ;
    BigInteger bigCode = new BigInteger(code);
    
    // 直接使用BigInteger的快速幂模计算,替代浮点Math.Pow
    BigInteger decodedMessage = BigInteger.ModPow(bigCode, d, pq);
    
    return (int)decodedMessage;
}

内容的提问来源于stack exchange,提问作者John Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 10:36:01