当前位置: 首页 > article >正文

C# BigInteger 的使用

总目录


前言

BigInteger 是 C# 提供的一种特殊数据类型,用于表示任意大小的整数。与传统的整数类型(如 int、long)相比,BigInteger 没有固定的大小限制,只受可用虚拟内存的限制,因此可以处理非常大的数值。本文将详细介绍 BigInteger 类的基本用法、常见操作以及一些实用技巧。


一、BigInteger 是什么?

1. 基本介绍

  • BigInteger 表示任意大有符号整数。
  • 继承:Object → ValueType → BigInteger
  • 位于 System.Numerics 命名空间

与传统数值类型不同,BigInteger不会被预先固定的内存大小所束缚。它就像一个智能的存储空间,能够依据所表示数字的规模,动态地调整内存分配。这一特性使它如同拥有了无限容量的口袋,能够轻松处理各种大小的整数,无论是日常的小额交易金额,还是天文学中星系间的庞大距离数值。

2. 创建与初始化BigInteger

  1. 通过常量初始化
			BigInteger num1 = 12345678901234567890;
  1. 通过构造函数创建
            BigInteger bigInt1 = new BigInteger(987654321);

            byte[] bytes = { 0x01, 0x02, 0x03, 0x04 };
            bigInt1 = new BigInteger(bytes);
  1. 通过使用静态方法 Parse 或 TryParse 从字符串转换。
            BigInteger bigInt2 = BigInteger.Parse("12345678901234567890");
  1. 从其他数值类型的隐式或显式转换。
			int smallInt = 42;
			BigInteger bigInt3 = smallInt; // 隐式转换

二、BigInteger 的优势与劣势

1. 优势

1)无限范围

由于 BigInteger 没有固定的大小,因此可以用来处理非常大的数字。

以计算阶乘为例,这是一个随着数字增大,普通整数类型迅速败下阵来的典型场景。普通的int或long类型,在面对较大数字的阶乘时,就像小水桶试图装下无尽的海水,很快就会溢出。而BigInteger则能轻松应对,如同一望无际的大海,容纳一切:

public static BigInteger Factorial(int n)
{
    BigInteger result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    return result;
}
        static void Main(string[] args)
        {
            BigInteger num1 = Program.Factorial(100);
            Console.WriteLine(num1);
            // 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
        }

2)精确计算

在高精度计算场景中,BigInteger不会出现精度丢失的问题。这对于金融计算、科学计算等领域意义重大。例如,在计算高精度圆周率时,BigInteger能保证结果的准确性。

2. 劣势

1)性能上存在劣势

由于BigInteger需要动态分配内存,并且在计算过程中需要调动更多的计算资源,这就好比一辆大型货车,虽然载货能力强,但启动和行驶速度相对较慢。在进行简单的加法运算时,int类型就像轻巧的摩托车,能够迅速完成任务,而BigInteger则需要更多的时间和资源来完成相同的操作:

static void Main(string[] args)
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i = 0; i < 1000000; i++)
    {
        int a = 1;
        int b = 2;
        int result = a + b;
    }
    stopwatch.Stop();
    Console.WriteLine($"int加法运算耗时: {stopwatch.ElapsedMilliseconds} 毫秒");

    stopwatch.Restart();
    for (int i = 0; i < 1000000; i++)
    {
        BigInteger a = 1;
        BigInteger b = 2;
        BigInteger result = a + b;
    }
    stopwatch.Stop();
    Console.WriteLine($"BigInteger加法运算耗时: {stopwatch.ElapsedMilliseconds} 毫秒");
}

输出结果:

int加法运算耗时: 2 毫秒
BigInteger加法运算耗时: 26 毫秒

2)存在内存不足的问题

随着所表示数字的不断增大,BigInteger占用的内存也会如气球般膨胀。在处理大量BigInteger数据时,就像在一个有限空间里不断堆积大型物品,很可能会导致内存不足的问题。例如,当我们创建一个包含大量超大BigInteger的列表时:

        static void Main(string[] args)
        {
            List<BigInteger> bigIntegerList = new List<BigInteger>();
            for (int i = 0; i < 10000; i++)
            {
                bigIntegerList.Add(BigInteger.Parse(new string('9', 100000)));
            }
        }

这段代码试图创建一个包含一万个长度为100000的全9数字的BigInteger列表,在运行过程中,很可能会因为内存占用过大而导致程序崩溃。

三、常用运算

BigInteger 支持常规的算术运算符(+、-、*、/、%),以及位移运算符(<<, >>)和逻辑运算符(&, |, ^)。此外,还支持比较运算符(==, !=, <, >, <=, >=)。

1. 算数运算

BigInteger a = 123;
BigInteger b = 456;
BigInteger sum = a + b;
BigInteger difference = a - b;
BigInteger product = a * b;
BigInteger quotient = a / b;
BigInteger remainder = a % b;

除以上直接通过运算符去计算之外,还可以使用由BingInteger 提供的静态方法

        public static BigInteger Add(BigInteger left, BigInteger right)
        {
            return left + right;
        }

        public static BigInteger Subtract(BigInteger left, BigInteger right)
        {
            return left - right;
        }

        public static BigInteger Multiply(BigInteger left, BigInteger right)
        {
            return left * right;
        }

        public static BigInteger Divide(BigInteger dividend, BigInteger divisor)
        {
            return dividend / divisor;
        }

        public static BigInteger Remainder(BigInteger dividend, BigInteger divisor)
        {
            return dividend % divisor;
        }
        static void Main(string[] args)
        {
            BigInteger bigInt1 = new BigInteger(987654321);
            BigInteger bigInt2 = BigInteger.Parse("12345678901234567890");

            BigInteger sum = BigInteger.Add(bigInt1, bigInt2);
            BigInteger difference = BigInteger.Subtract(bigInt1, bigInt2);
            BigInteger product = BigInteger.Multiply(bigInt1, bigInt2);
            BigInteger quotient = BigInteger.Divide(bigInt1, bigInt2);
        }

2. 比较运算

BigInteger x = 100;
BigInteger y = 200;
bool isLessThan = x < y;
bool isGreaterThan = x > y;
bool isEqual = x == y;

3. 位运算

BigInteger m = 5; // 二进制为 101
BigInteger n = 3; // 二进制为 011
BigInteger andResult = m & n; // 按位与,结果为 001
BigInteger orResult = m | n; // 按位或,结果为 111
BigInteger xorResult = m ^ n; // 按位异或,结果为 110

4. 其他常用方法

        public static BigInteger Max(BigInteger left, BigInteger right)
        {
            if (left.CompareTo(right) < 0)
                return right;
            return left;
        }

        public static BigInteger Min(BigInteger left, BigInteger right)
        {
            if (left.CompareTo(right) <= 0)
                return left;
            return right;
        }

在这里插入图片描述
更多详情可见:System.Numerics.BigInteger 结构、BigInteger 结构

四、数据转换

1. 转换为数值类型

			BigInteger bigInt = 123;
			int normalInt = (int)bigInt;

但需要格外注意的是,如果BigInteger的值超出了目标类型的范围,就像试图将一个大箱子塞进一个小盒子,转换会导致数据丢失或引发异常。比如:

        static void Main(string[] args)
        {
            BigInteger tooBigInt = 2147483648; // 超出int范围
            try
            {
                int normalInt = (int)tooBigInt;
            }
            catch (OverflowException ex)
            {
                Console.WriteLine($"转换时发生溢出异常: {ex.Message}");
            }
        }

2. 转换为字符串

			BigInteger num = 12345678901234567890;
			string numStr = num.ToString();

五、应用场景

1. 密码学领域的坚固堡垒

在加密算法的神秘世界里,BigInteger就像一位忠诚的卫士,守护着信息的安全。加密算法常常需要处理极大的质数,这些质数就像密码锁的复杂密码,只有通过BigInteger的强大能力,才能准确地生成和处理。例如,在RSA加密算法中,需要使用极大的整数来进行加密和解密操作,BigInteger能够完美地满足这一需求,确保加密的安全性如同坚固的堡垒:

// RSA加密算法中使用BigInteger的简单示例
BigInteger p = BigInteger.Parse("123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200");
BigInteger q = BigInteger.Parse("201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400");
// 后续进行复杂的RSA计算步骤

2. 科学计算领域的得力助手

在天文学、物理学等科学领域的浩瀚宇宙中,BigInteger是科学家们的得力助手。这些领域常常涉及极大或极小的数值计算,如计算星系之间的距离,那是一个遥远到难以想象的数字,普通数值类型望尘莫及;还有微观粒子的质量,微小到几乎无法用常规方式表示。而BigInteger凭借其强大的能力,能够精准地进行这些计算,为科学研究提供坚实的支持:

// 简单模拟计算星系间距离(实际数据和计算会更复杂)
BigInteger distanceUnit = BigInteger.Parse("100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

六. 注意事项

  • 在进行涉及 BigInteger 的除法操作时,如果除数为零,会抛出 DivideByZeroException。
  • 当将 BigInteger 转换为较小的数值类型时,如果超出目标类型的范围,则会引发 OverflowException,除非启用了检查溢出的编译器选项。
  • BigInteger 是不可变的;每次执行修改操作都会生成新的 BigInteger 实例。
  • 精度问题
    • 虽然BigInteger在整数运算中保证精度,但在与浮点数相关的转换或运算中,可能会出现精度丢失。例如,将BigInteger转换为float或double时,由于浮点数的表示精度有限,可能无法精确表示BigInteger的值。
    • 因此,在涉及精度要求极高的场景,尤其是从BigInteger转换为浮点数类型时,需要谨慎处理。

结语

回到目录页:C# 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
System.Numerics.BigInteger 结构
BigInteger 结构
C# BigInteger 处理超大整型数字


http://www.kler.cn/a/470944.html

相关文章:

  • nginx-灰度发布策略(基于cookie)
  • Django:构建高效Web应用的强大框架
  • Pytorch初学
  • Swin-Transformer
  • ubuntu开机启动服务
  • 【AI落地】AI生成测试用例,claude or gpt?(提效至少 50%)
  • 『SQLite』约束怎么用
  • linux ansible部署
  • Qt|麦克风设备热插拔检测功能
  • 网络安全领域中PHP防范常用语法
  • 安卓H5项目通过adb更新H5项目
  • jQuery二次元风格右键菜单插件HTML源码
  • C++ Latch 和 Barrier: 新手指南
  • 【网络云SRE运维开发】2025第1周-每日【2025/01/04】小测-【第5章 交换机的工作原理】理论和实操
  • 用c++构建的actor导致整个ue5蓝图项目打不开。
  • java 转义 反斜杠 Unexpected internal error near index 1
  • (leetcode算法题)371. 两整数之和
  • xilinx的高速接口构成原理和连接结构及ibert工具的使用-以k7 GTX为例
  • Ubuntu-bk搭建
  • springboot547产业园区智慧公寓管理系统(论文+源码)_kaic
  • PHP如何删除数组中的特定值?
  • 小R的蛋糕分享
  • 企业级Nosql数据库和Redis集群
  • 查找路由器的管理后台ip【通用找IP】
  • 在高德地图上加载3DTilesLayer图层模型/天地瓦片
  • excel填充十六进制