本文提供了此 API 参考文档的补充说明。
该 BigInteger 类型是一个不可变类型,表示一个任意较大的整数,其理论上的值没有上限或下限。 类型 BigInteger 的成员紧密平行与其他整型类型的成员 (Byte、Int16、Int32、Int64、SByte、UInt16、UInt32 和 UInt64 类型)。 此类型不同于 .NET 中的其他整型类型,这些类型具有由其 MinValue
和 MaxValue
属性指示的范围。
注释
因为 BigInteger 类型是不可变的(请参阅可变性)并且没有上限或下限,所以任何导致 OutOfMemoryException 值变得过大的操作都可能引发 BigInteger。
实例化 BigInteger 对象
可以通过多种方式实例化 BigInteger 对象:
可以使用
new
关键字,并向构造函数提供任何整型或浮点值作为参数 BigInteger 。 (浮点值在分配给 BigInteger 之前被截断。)下面的示例演示如何使用new
关键字实例化 BigInteger 值。BigInteger bigIntFromDouble = new BigInteger(179032.6541); Console.WriteLine(bigIntFromDouble); BigInteger bigIntFromInt64 = new BigInteger(934157136952); Console.WriteLine(bigIntFromInt64); // The example displays the following output: // 179032 // 934157136952
Dim bigIntFromDouble As New BigInteger(179032.6541) Console.WriteLine(bigIntFromDouble) Dim bigIntFromInt64 As New BigInteger(934157136952) Console.WriteLine(bigIntFromInt64) ' The example displays the following output: ' 179032 ' 934157136952
可以声明变量 BigInteger 并将其赋值,就像任何数值类型一样,只要该值是整型类型。 以下示例通过赋值从BigInteger创建Int64值。
long longValue = 6315489358112; BigInteger assignedFromLong = longValue; Console.WriteLine(assignedFromLong); // The example displays the following output: // 6315489358112
Dim longValue As Long = 6315489358112 Dim assignedFromLong As BigInteger = longValue Console.WriteLine(assignedFromLong) ' The example displays the following output: ' 6315489358112
如果先对值进行强制转换或转换,就可以将小数或浮点值赋给 BigInteger 对象。 以下示例显式地将(C# 中的)Double 和 Decimal 值转换为(Visual Basic 中的)BigInteger。
BigInteger assignedFromDouble = (BigInteger) 179032.6541; Console.WriteLine(assignedFromDouble); BigInteger assignedFromDecimal = (BigInteger) 64312.65m; Console.WriteLine(assignedFromDecimal); // The example displays the following output: // 179032 // 64312
Dim assignedFromDouble As BigInteger = CType(179032.6541, BigInteger) Console.WriteLine(assignedFromDouble) Dim assignedFromDecimal As BigInteger = CType(64312.65D, BigInteger) Console.WriteLine(assignedFromDecimal) ' The example displays the following output: ' 179032 ' 64312
这些方法使你能够实例化 BigInteger 其值仅在现有数值类型之一范围内的对象。 可以实例化一个 BigInteger 对象,其值可以通过以下三种方式之一超过现有数值类型的范围:
可以使用
new
关键字并向构造函数提供任何大小的 BigInteger.BigInteger 字节数组。 例如:byte[] byteArray = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; BigInteger newBigInt = new BigInteger(byteArray); Console.WriteLine($"The value of newBigInt is {newBigInt} (or 0x{newBigInt:x})."); // The example displays the following output: // The value of newBigInt is 4759477275222530853130 (or 0x102030405060708090a).
Dim byteArray() As Byte = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0} Dim newBigInt As New BigInteger(byteArray) Console.WriteLine("The value of newBigInt is {0} (or 0x{0:x}).", newBigInt) ' The example displays the following output: ' The value of newBigInt is 4759477275222530853130 (or 0x102030405060708090a).
可以调用 Parse 或 TryParse 方法将数字的字符串表示形式转换为 a BigInteger. 例如:
string positiveString = "91389681247993671255432112000000"; string negativeString = "-90315837410896312071002088037140000"; BigInteger posBigInt = 0; BigInteger negBigInt = 0; try { posBigInt = BigInteger.Parse(positiveString); Console.WriteLine(posBigInt); } catch (FormatException) { Console.WriteLine($"Unable to convert the string '{positiveString}' to a BigInteger value."); } if (BigInteger.TryParse(negativeString, out negBigInt)) Console.WriteLine(negBigInt); else Console.WriteLine($"Unable to convert the string '{negativeString}' to a BigInteger value."); // The example displays the following output: // 9.1389681247993671255432112E+31 // -9.0315837410896312071002088037E+34
Dim positiveString As String = "91389681247993671255432112000000" Dim negativeString As String = "-90315837410896312071002088037140000" Dim posBigInt As BigInteger = 0 Dim negBigInt As BigInteger = 0 Try posBigInt = BigInteger.Parse(positiveString) Console.WriteLine(posBigInt) Catch e As FormatException Console.WriteLine("Unable to convert the string '{0}' to a BigInteger value.", positiveString) End Try If BigInteger.TryParse(negativeString, negBigInt) Then Console.WriteLine(negBigInt) Else Console.WriteLine("Unable to convert the string '{0}' to a BigInteger value.", negativeString) End If ' The example displays the following output: ' 9.1389681247993671255432112E+31 ' -9.0315837410896312071002088037E+34
可以调用
static
方法(在 Visual Basic 中的Shared
BigInteger),对数值表达式执行某些操作并返回计算 BigInteger 结果。 以下示例通过将 UInt64.MaxValue 立方并将结果赋值给 BigInteger 来实现这一功能。BigInteger number = BigInteger.Pow(UInt64.MaxValue, 3); Console.WriteLine(number); // The example displays the following output: // 6277101735386680762814942322444851025767571854389858533375
Dim number As BigInteger = BigInteger.Pow(UInt64.MaxValue, 3) Console.WriteLine(number) ' The example displays the following output: ' 6277101735386680762814942322444851025767571854389858533375
未初始化的BigInteger的值是Zero.
对 BigInteger 值执行操作
可以使用 BigInteger 实例,就像使用任何其他整型类型一样。
BigInteger 重载标准数值运算符,使你能够执行基本的数学运算,例如加法、减法、除法、乘法和一元求反。 还可以使用标准数值运算符来比较两 BigInteger 个值。 与其他整数类型一样,BigInteger 也支持按位 And
、Or
、XOr
、左移和右移运算符。 对于不支持自定义运算符的语言,该 BigInteger 结构还提供用于执行数学运算的等效方法。 这些包括Add、Divide、Multiply、Negate、Subtract及其他几个项目。
结构中的 BigInteger 许多成员直接对应于其他整型类型的成员。 此外, BigInteger 添加如下成员:
Sign,返回一个表示 BigInteger 值符号的值。
Abs,返回 BigInteger 值的绝对值。
DivRem,同时返回除法运算的商和余数。
GreatestCommonDivisor,返回两个 BigInteger 值的最大公约数。
许多这些附加成员对应于Math类的成员,该类提供了处理基元数值类型的功能。
可变性
以下示例实例化一个 BigInteger 对象,然后将其值递增一个。
BigInteger number = BigInteger.Multiply(Int64.MaxValue, 3);
number++;
Console.WriteLine(number);
Dim number As BigInteger = BigInteger.Multiply(Int64.MaxValue, 3)
number += 1
Console.WriteLine(number)
尽管此示例似乎修改现有对象的值,但情况并非如此。 BigInteger 对象是不可变的,这意味着在内部,公共语言运行时实际上会创建一个新 BigInteger 对象,并为其分配一个大于其先前值的值。 然后,此新对象将返回到调用方。
注释
.NET 中的其他数值类型也是不可变的。 但是,由于 BigInteger 该类型没有上限或下限,因此其值可能会增长非常大,并且会对性能产生可衡量的影响。
尽管此过程对调用方是透明的,但它确实会产生性能损失。 在某些情况下,尤其是在循环中对非常大的BigInteger值执行重复操作时,可能会导致显著的性能损失。 例如,在下面的示例中,一个操作会重复执行达一百万次,每次操作成功后,BigInteger 值都会递增一。
BigInteger number = Int64.MaxValue ^ 5;
int repetitions = 1000000;
// Perform some repetitive operation 1 million times.
for (int ctr = 0; ctr <= repetitions; ctr++)
{
// Perform some operation. If it fails, exit the loop.
if (!SomeOperationSucceeds()) break;
// The following code executes if the operation succeeds.
number++;
}
Dim number As BigInteger = Int64.MaxValue ^ 5
Dim repetitions As Integer = 1000000
' Perform some repetitive operation 1 million times.
For ctr As Integer = 0 To repetitions
' Perform some operation. If it fails, exit the loop.
If Not SomeOperationSucceeds() Then Exit For
' The following code executes if the operation succeeds.
number += 1
Next
在这种情况下,可以通过对变量执行所有中间赋值 Int32 来提高性能。 然后,变量的最终值可以在循环退出时分配给 BigInteger 对象。 下面的示例进行了这方面的演示。
BigInteger number = Int64.MaxValue ^ 5;
int repetitions = 1000000;
int actualRepetitions = 0;
// Perform some repetitive operation 1 million times.
for (int ctr = 0; ctr <= repetitions; ctr++)
{
// Perform some operation. If it fails, exit the loop.
if (!SomeOperationSucceeds()) break;
// The following code executes if the operation succeeds.
actualRepetitions++;
}
number += actualRepetitions;
Dim number As BigInteger = Int64.MaxValue ^ 5
Dim repetitions As Integer = 1000000
Dim actualRepetitions As Integer = 0
' Perform some repetitive operation 1 million times.
For ctr As Integer = 0 To repetitions
' Perform some operation. If it fails, exit the loop.
If Not SomeOperationSucceeds() Then Exit For
' The following code executes if the operation succeeds.
actualRepetitions += 1
Next
number += actualRepetitions
字节数组和十六进制字符串
如果将值转换为 BigInteger 字节数组,或者将字节数组转换为 BigInteger 值,则必须考虑字节的顺序。 该 BigInteger 结构要求字节数组中的单个字节以小字节顺序显示(也就是说,该值的下序字节位于高阶字节之前)。 可以通过调用BigInteger该方法,然后将生成的字节数组传递给ToByteArray构造函数来往返BigInteger(Byte[])值,如以下示例所示。
BigInteger number = BigInteger.Pow(Int64.MaxValue, 2);
Console.WriteLine(number);
// Write the BigInteger value to a byte array.
byte[] bytes = number.ToByteArray();
// Display the byte array.
foreach (byte byteValue in bytes)
Console.Write("0x{0:X2} ", byteValue);
Console.WriteLine();
// Restore the BigInteger value from a Byte array.
BigInteger newNumber = new BigInteger(bytes);
Console.WriteLine(newNumber);
// The example displays the following output:
// 8.5070591730234615847396907784E+37
// 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x3F
//
// 8.5070591730234615847396907784E+37
Dim number As BigInteger = BigInteger.Pow(Int64.MaxValue, 2)
Console.WriteLine(number)
' Write the BigInteger value to a byte array.
Dim bytes() As Byte = number.ToByteArray()
' Display the byte array.
For Each byteValue As Byte In bytes
Console.Write("0x{0:X2} ", byteValue)
Next
Console.WriteLine()
' Restore the BigInteger value from a Byte array.
Dim newNumber As BigInteger = New BigInteger(bytes)
Console.WriteLine(newNumber)
' The example displays the following output:
' 8.5070591730234615847396907784E+37
' 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x3F
'
' 8.5070591730234615847396907784E+37
若要实例化 BigInteger 表示其他一些整型类型的值的字节数组中的值,可以将整型值 BitConverter.GetBytes 传递给方法,然后将生成的字节数组传递给 BigInteger(Byte[]) 构造函数。 以下示例实例化一个 BigInteger 值,来自表示 Int16 值的字节数组。
short originalValue = 30000;
Console.WriteLine(originalValue);
// Convert the Int16 value to a byte array.
byte[] bytes = BitConverter.GetBytes(originalValue);
// Display the byte array.
foreach (byte byteValue in bytes)
Console.Write("0x{0} ", byteValue.ToString("X2"));
Console.WriteLine();
// Pass byte array to the BigInteger constructor.
BigInteger number = new BigInteger(bytes);
Console.WriteLine(number);
// The example displays the following output:
// 30000
// 0x30 0x75
// 30000
Dim originalValue As Short = 30000
Console.WriteLine(originalValue)
' Convert the Int16 value to a byte array.
Dim bytes() As Byte = BitConverter.GetBytes(originalValue)
' Display the byte array.
For Each byteValue As Byte In bytes
Console.Write("0x{0} ", byteValue.ToString("X2"))
Next
Console.WriteLine()
' Pass byte array to the BigInteger constructor.
Dim number As BigInteger = New BigInteger(bytes)
Console.WriteLine(number)
' The example displays the following output:
' 30000
' 0x30 0x75
' 30000
BigInteger 结构假定负值使用二进制补码表示来存储。 BigInteger由于结构表示没有固定长度的数值,BigInteger(Byte[])因此构造函数始终将数组中最后一个字节的最有效位解释为符号位。 为防止 BigInteger(Byte[]) 构造函数将负值的二进制补码表示与正值的符号和大小表示相混淆,如果字节数组中最后一个字节的最重要位通常被置位,则正值应包括一个额外的字节,其值为 0。 例如,0xC0 0xBD 0xF0 0xFF是 -1,000,000 或 4,293,967,296 的小数十六进制表示形式。 因为此数组中最后一个字节的最高有效位处于打开状态,所以 BigInteger(Byte[]) 构造函数会将字节数组的值解释为 -1,000,000。 若要实例化 BigInteger 其值为正的字节数组,必须将其元素0xC0 0xBD 0xF0 0xFF 0x00的字节数组传递给构造函数。 下面的示例对此进行了演示。
int negativeNumber = -1000000;
uint positiveNumber = 4293967296;
byte[] negativeBytes = BitConverter.GetBytes(negativeNumber);
BigInteger negativeBigInt = new BigInteger(negativeBytes);
Console.WriteLine(negativeBigInt.ToString("N0"));
byte[] tempPosBytes = BitConverter.GetBytes(positiveNumber);
byte[] positiveBytes = new byte[tempPosBytes.Length + 1];
Array.Copy(tempPosBytes, positiveBytes, tempPosBytes.Length);
BigInteger positiveBigInt = new BigInteger(positiveBytes);
Console.WriteLine(positiveBigInt.ToString("N0"));
// The example displays the following output:
// -1,000,000
// 4,293,967,296
Dim negativeNumber As Integer = -1000000
Dim positiveNumber As UInteger = 4293967296
Dim negativeBytes() As Byte = BitConverter.GetBytes(negativeNumber)
Dim negativeBigInt As New BigInteger(negativeBytes)
Console.WriteLine(negativeBigInt.ToString("N0"))
Dim tempPosBytes() As Byte = BitConverter.GetBytes(positiveNumber)
Dim positiveBytes(tempposBytes.Length) As Byte
Array.Copy(tempPosBytes, positiveBytes, tempPosBytes.Length)
Dim positiveBigInt As New BigInteger(positiveBytes)
Console.WriteLine(positiveBigInt.ToString("N0"))
' The example displays the following output:
' -1,000,000
' 4,293,967,296
由 ToByteArray 正值方法创建的字节数组包括此额外的零值字节。 因此,BigInteger 结构可以通过将值分配给字节数组,然后从字节数组中还原它们,从而成功实现值的往返转换,如以下示例所示。
BigInteger positiveValue = 15777216;
BigInteger negativeValue = -1000000;
Console.WriteLine("Positive value: " + positiveValue.ToString("N0"));
byte[] bytes = positiveValue.ToByteArray();
foreach (byte byteValue in bytes)
Console.Write("{0:X2} ", byteValue);
Console.WriteLine();
positiveValue = new BigInteger(bytes);
Console.WriteLine("Restored positive value: " + positiveValue.ToString("N0"));
Console.WriteLine();
Console.WriteLine("Negative value: " + negativeValue.ToString("N0"));
bytes = negativeValue.ToByteArray();
foreach (byte byteValue in bytes)
Console.Write("{0:X2} ", byteValue);
Console.WriteLine();
negativeValue = new BigInteger(bytes);
Console.WriteLine("Restored negative value: " + negativeValue.ToString("N0"));
// The example displays the following output:
// Positive value: 15,777,216
// C0 BD F0 00
// Restored positive value: 15,777,216
//
// Negative value: -1,000,000
// C0 BD F0
// Restored negative value: -1,000,000
Dim positiveValue As BigInteger = 15777216
Dim negativeValue As BigInteger = -1000000
Console.WriteLine("Positive value: " + positiveValue.ToString("N0"))
Dim bytes() As Byte = positiveValue.ToByteArray()
For Each byteValue As Byte In bytes
Console.Write("{0:X2} ", byteValue)
Next
Console.WriteLine()
positiveValue = New BigInteger(bytes)
Console.WriteLine("Restored positive value: " + positiveValue.ToString("N0"))
Console.WriteLine()
Console.WriteLIne("Negative value: " + negativeValue.ToString("N0"))
bytes = negativeValue.ToByteArray()
For Each byteValue As Byte In bytes
Console.Write("{0:X2} ", byteValue)
Next
Console.WriteLine()
negativeValue = New BigInteger(bytes)
Console.WriteLine("Restored negative value: " + negativeValue.ToString("N0"))
' The example displays the following output:
' Positive value: 15,777,216
' C0 BD F0 00
' Restored positive value: 15,777,216
'
' Negative value: -1,000,000
' C0 BD F0
' Restored negative value: -1,000,000
然而,您可能需要将这个零值字节额外添加到由开发人员动态生成的字节数组中,或者添加到使用将无符号整数转换为字节数组的方法返回的字节数组中(例如BitConverter.GetBytes(UInt16)、BitConverter.GetBytes(UInt32) 和BitConverter.GetBytes(UInt64))。
解析十六进制字符串时,BigInteger.Parse(String, NumberStyles) 和 BigInteger.Parse(String, NumberStyles, IFormatProvider) 方法假定如果字符串中第一个字节的最高有效位被设置,或者字符串的第一个十六进制数字表示字节值的低四位,则使用二进制补码表示法来表示该值。 例如,“FF01”和“F01”都表示十进制值 -255。 若要将正值与负值区分开来,正值应包括前导零。 ToString 方法的相关重载在传递“X”格式字符串时,会在返回的十六进制字符串中为正值添加前导零。 这使得可以使用 BigInteger 和 ToString 方法往返 Parse 值,如以下示例所示。
BigInteger negativeNumber = -1000000;
BigInteger positiveNumber = 15777216;
string negativeHex = negativeNumber.ToString("X");
string positiveHex = positiveNumber.ToString("X");
BigInteger negativeNumber2, positiveNumber2;
negativeNumber2 = BigInteger.Parse(negativeHex,
NumberStyles.HexNumber);
positiveNumber2 = BigInteger.Parse(positiveHex,
NumberStyles.HexNumber);
Console.WriteLine($"Converted {negativeNumber:N0} to {negativeHex} back to {negativeNumber2:N0}.");
Console.WriteLine($"Converted {positiveNumber:N0} to {positiveHex} back to {positiveNumber2:N0}.");
// The example displays the following output:
// Converted -1,000,000 to F0BDC0 back to -1,000,000.
// Converted 15,777,216 to 0F0BDC0 back to 15,777,216.
Dim negativeNumber As BigInteger = -1000000
Dim positiveNumber As BigInteger = 15777216
Dim negativeHex As String = negativeNumber.ToString("X")
Dim positiveHex As string = positiveNumber.ToString("X")
Dim negativeNumber2, positiveNumber2 As BigInteger
negativeNumber2 = BigInteger.Parse(negativeHex,
NumberStyles.HexNumber)
positiveNumber2 = BigInteger.Parse(positiveHex,
NumberStyles.HexNumber)
Console.WriteLine("Converted {0:N0} to {1} back to {2:N0}.",
negativeNumber, negativeHex, negativeNumber2)
Console.WriteLine("Converted {0:N0} to {1} back to {2:N0}.",
positiveNumber, positiveHex, positiveNumber2)
' The example displays the following output:
' Converted -1,000,000 to F0BDC0 back to -1,000,000.
' Converted 15,777,216 to 0F0BDC0 back to 15,777,216.
但是,通过调用其他整型类型的ToString
方法或包含ToString参数的toBase
方法重载创建的十六进制字符串,并不表示值的符号或派生该十六进制字符串的源数据类型。 成功实例化 BigInteger 此类字符串中的值需要一些额外的逻辑。 以下示例提供了一个可能的实现。
using System;
using System.Globalization;
using System.Numerics;
public struct HexValue
{
public int Sign;
public string Value;
}
public class ByteHexExample2
{
public static void Main()
{
uint positiveNumber = 4039543321;
int negativeNumber = -255423975;
// Convert the numbers to hex strings.
HexValue hexValue1, hexValue2;
hexValue1.Value = positiveNumber.ToString("X");
hexValue1.Sign = Math.Sign(positiveNumber);
hexValue2.Value = Convert.ToString(negativeNumber, 16);
hexValue2.Sign = Math.Sign(negativeNumber);
// Round-trip the hexadecimal values to BigInteger values.
string hexString;
BigInteger positiveBigInt, negativeBigInt;
hexString = (hexValue1.Sign == 1 ? "0" : "") + hexValue1.Value;
positiveBigInt = BigInteger.Parse(hexString, NumberStyles.HexNumber);
Console.WriteLine($"Converted {positiveNumber} to {hexValue1.Value} and back to {positiveBigInt}.");
hexString = (hexValue2.Sign == 1 ? "0" : "") + hexValue2.Value;
negativeBigInt = BigInteger.Parse(hexString, NumberStyles.HexNumber);
Console.WriteLine($"Converted {negativeNumber} to {hexValue2.Value} and back to {negativeBigInt}.");
}
}
// The example displays the following output:
// Converted 4039543321 to F0C68A19 and back to 4039543321.
// Converted -255423975 to f0c68a19 and back to -255423975.
Imports System.Globalization
Imports System.Numerics
Public Structure HexValue
Public Sign As Integer
Public Value As String
End Structure
Module Example2
Public Sub Main()
Dim positiveNumber As UInteger = 4039543321
Dim negativeNumber As Integer = -255423975
' Convert the numbers to hex strings.
Dim hexValue1, hexValue2 As HexValue
hexValue1.Value = positiveNumber.ToString("X")
hexValue1.Sign = Math.Sign(positiveNumber)
hexValue2.Value = Convert.ToString(negativeNumber, 16)
hexValue2.Sign = Math.Sign(negativeNumber)
' Round-trip the hexadecimal values to BigInteger values.
Dim hexString As String
Dim positiveBigInt, negativeBigInt As BigInteger
hexString = CStr(IIf(hexValue1.Sign = 1, "0", "")) + hexValue1.Value
positiveBigInt = BigInteger.Parse(hexString, NumberStyles.HexNumber)
Console.WriteLine("Converted {0} to {1} and back to {2}.",
positiveNumber, hexValue1.Value, positiveBigInt)
hexString = CStr(IIf(hexValue2.Sign = 1, "0", "")) + hexValue2.Value
negativeBigInt = BigInteger.Parse(hexString, NumberStyles.HexNumber)
Console.WriteLine("Converted {0} to {1} and back to {2}.",
negativeNumber, hexValue2.Value, negativeBigInt)
End Sub
End Module
' The example displays the following output:
' Converted 4039543321 to F0C68A19 and back to 4039543321.
' Converted -255423975 to f0c68a19 and back to -255423975.