跳转到主内容
极星编程网:以代码为星,赴技术山海!

C# BigInteger使用方法 C#如何处理超出long范围的大整数

BigInteger 是 System.Numerics 下的不可变任意精度整数类型,内存随位数增长,避免 long 的静默溢出;需通过 Parse、隐式转换或构造函数初始化,不支持直接字面量赋值。 BigInteger 是什么,为什么不能直接用 long
BigInteger
是
System.Numerics
命名空间下的不可变类型,专为任意精度整数设计。它不占固定 字节 (不像
long
固定 8 字节、上限
9223372036854775807
),内存占用随数值位数增长。一旦运算结果超过
long.MaxValue
或低于
long.MinValue
,继续用
long
会静默溢出(无异常,但值错误),而
BigInteger
自动扩容,避免这类陷阱。 如何声明和初始化 BigInteger 不能像基本类型那样直接赋字面量(
123456789012345678901234567890
编译不过),必须通过构造函数或 隐式转换 。常见方式: 从 字符串解析 :
var big = BigInteger.Parse("123456789012345678901234567890")
从
long
/
int
隐式转换:
BigInteger big = 123L
(安全,因为小整数可无损表示) 从字节数组(需注意符号位和字节序):
new BigInteger(bytes)
,常用于序列化/反序列化场景 使用静态属性:
BigInteger.Zero
、
BigInteger.One
、
BigInteger.MinusOne
⚠️ 注意:
BigInteger.Parse()
默认不接受带下划线的数字分隔符(如
"1_000_000"
),会抛
FormatException
;也不支持十六进制前缀
"0x"
,除非用重载
BigInteger.Parse(s, NumberStyles.HexNumber)
。 常用运算与性能注意事项
BigInteger
支持全部标准算术运算符(
+
、
-
、
*
、
/
、
%
)、比较运算符和位运算(
&
、
|
、
^
、
<<
、
>>
),用法和
int
/
long
一致。但背后是大数算法(如 Karatsuba 乘法),性能差异显著: 加减法:O(n),n 是位数,通常够快 乘法:对超长数(万位以上)可能明显慢于
long
,别在 tight loop 里反复做
BigInteger
乘方 除法和模运算:最重,尤其
%
在密码学循环中要谨慎 避免频繁装箱/拆箱:它本身是 struct,但内部引用大数组,大量短生命周期实例会增加 GC 压力 示例:计算阶乘(演示溢出规避)
BigInteger Factorial(int n) { BigInteger result = 1; for (int i = 2; i <= n; i++) { result *= i; // 不会溢出 } return result; } Console.WriteLine(Factorial(100)); // 正常输出 158 位数字
序列化与跨平台兼容性坑
BigInteger
默认不支持 JSON.NET 或
System.Text.Json
直接序列化(.NET 6+ 的
System.Text.Json
才内置支持)。若用老版本或自定义协议: 推荐存为十进制字符串:
big.ToString()
,最通用、无歧义 避免用
ToArray()
后直接存——不同 .NET 实现(如 .NET Framework vs .NET Core)对符号字节位置约定不一致,反序列化可能出错 若必须二进制传输,用
BigInteger.ToByteArray()
+ 显式处理符号(末字节最高位为符号位),且接收端必须用相同逻辑还原 在 ASP.NET Core API 中返回
BigInteger
属性时,确保启用
JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString
(针对字符串输入),否则前端传字符串会绑定失败 真正麻烦的不是“怎么算”,而是“怎么让别人(或下次运行)正确读回来”——字符串表示虽冗余,却是最省心的选择。

相关文章