应直接使用 system.numerics.biginteger,因其内置高精度运算且无需手动实现;需显式添加 using system.numerics; 和引用 system.numerics.dll;parse 抛异常而 tryparse 返回布尔值;biginteger 不可变,所有运算返回新实例;tostring() 有性能与格式隐患,推荐 tobytearray() 序列化。

直接用 System.Numerics.BigInteger,别自己写字符串/数组模拟——除非你明确需要控制内存布局、精度截断或兼容 .NET 3.5(如旧版 Unity)。
为什么必须加 using System.Numerics; 才能用 BigInteger
因为 BigInteger 不在默认命名空间里,它属于独立的程序集 System.Numerics.dll。即使你用的是 .NET 6+ 或 .NET Framework 4.0+,漏掉这行引用,编译器会报错:The type or namespace name 'BigInteger' could not be found。VS 有时会自动补全,但 CI 构建或手动编辑 csproj 时容易遗漏。确认项目文件中已包含:
<itemgroup><reference include="System.Numerics"></reference></itemgroup>
对于 SDK 风格项目(.NET Core/.NET 5+),通常无需显式添加,但若目标框架是 netcoreapp2.0 或 net5.0 且仍报错,检查是否误删了隐式引用。
BigInteger.Parse() 和 BigInteger.TryParse() 的实际差异
二者都支持十进制字符串输入,但错误处理方式完全不同:
-
BigInteger.Parse("abc")直接抛出FormatException,无法捕获就崩; -
BigInteger.TryParse("abc", out var result)返回false,result被设为0,适合用户输入、日志解析等不可信来源。
注意:两者都不支持带千分位分隔符(如 "1,234,567")或前导空格(" 123")——必须是纯数字串,可带可不带正负号。若需宽松解析,得先用 string.Trim() 和正则清洗。
算术运算后值不变?那是你忽略了 BigInteger 的不可变性
BigInteger 是不可变结构体(immutable),所有运算(+、*、++ 等)都返回新实例,原变量不会被修改:
BigInteger a = BigInteger.One; a += BigInteger.One; // ✅ 看似“修改”,其实是 a = a + 1 的语法糖,生成新对象 BigInteger b = a; a *= 2; // ❌ 这里 b 仍等于 2,a 变成 4 —— b 和 a 指向不同实例
这意味着:
- 频繁循环累加(如阶乘)会产生大量中间对象,GC 压力明显;
- 不能靠“引用传递”共享状态,函数传参后修改不影响调用方原始值;
- 没有
+=的底层优化,每次都是分配+拷贝,大数据量时比原生类型慢一个数量级。
输出大数时 ToString() 的隐藏坑
ToString() 默认输出十进制,但遇到超长结果(比如 10000 位)时,字符串构造本身可能成为性能瓶颈。更关键的是格式化行为:
-
big.ToString("X")输出大写十六进制,但不补前导零,且符号位单独处理(负数输出"-ABC"而非二补码); -
big.ToString("N0")会尝试加千分位,但对超长整数可能抛OutOfMemoryException(内部缓存过大); - 若需固定长度十六进制(如哈希补零),必须手动:
big.ToByteArray()得到小端字节数组,再转BitConverter.ToString()并替换短横线。
真正要落地的场景(如密码学密钥导出、链上交易签名),别依赖 ToString() 做序列化——用 ToByteArray() + Base64 或十六进制编码更可控、无歧义。
最常被忽略的一点:BigInteger 没有字面量语法,也不能和 int/long 混合隐式运算。写 var x = 123456789012345678901234567890 + big 会编译失败,必须显式转换或统一用 BigInteger 构造。











