System.Numerics.BigInteger 結構

本文提供此 API 參考文件的補充備註。

BigInteger 類型是不可變的類型,代表任意大整數,理論上其值沒有上限或下限。 型別的成員BigInteger會密切平行處理其他整數型別的成員(ByteInt16Int32Int64SByte、、、 UInt16UInt32UInt64 型別)。 此類型與 .NET 中的其他整數型別不同,其範圍是以其 MinValueMaxValue 屬性表示。

注意

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 變數併為其指派值,就如同任何數值類型一樣。 下列範例會使用指派從 建立 BigIntegerInt64

    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# 中)或將 (在 Visual Basic 中) DoubleDecimalBigInteger轉換成 。

    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 {0} (or 0x{0:x}).", newBigInt);
    // 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).
    
  • 您可以呼叫 ParseTryParse 方法,將數位的字串表示轉換成 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 '{0}' to a BigInteger value.",
                         positiveString);
    }
    
    if (BigInteger.TryParse(negativeString, out negBigInt))
      Console.WriteLine(negBigInt);
    else
       Console.WriteLine("Unable to convert the string '{0}' to a BigInteger value.",
                          negativeString);
    
    // 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 在數值表達式上執行某些運算的 (Shared 在 Visual Basic 中為 ) 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
    

未初始化的值 BigIntegerZero

對 BigInteger 值執行作業

您可以使用 BigInteger 實例,就像使用任何其他整數類型一樣。 BigInteger 多載標準數值運算符,可讓您執行基本的數學運算,例如加法、減法、除法、乘法和一元負數。 您也可以使用標準數值運算符來比較兩個 BigInteger 值。 與其他整數類型一樣, BigInteger 也支援位 AndOr、、 XOr左移和右移運算符。 對於不支援自定義運算符的語言,結構 BigInteger 也提供執行數學運算的對等方法。 這些包括 AddDivideMultiplyNegateSubtract和數個其他專案。

結構的許多 BigInteger 成員會直接對應至其他整數型別的成員。 此外, 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 物件是不可變的,這表示在內部,Common Language Runtime 實際上會建立新的 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 預期位元組陣列中的個別位元組會以小到小的順序出現(也就是值下限的位元組在較高順序的位元組之前)。 您可以呼叫 ToByteArray 方法,然後將產生的位元組陣列傳遞至BigInteger(Byte[])建構函式,以往返BigInteger值,如下列範例所示。

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[]) 建構函式。 下列範例會從代表Int16值的位元組數位化BigInteger值。

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」 格式字串時,將前置零加入傳回的十六進位字串中,以取得正值。 這可讓您使用 ToStringParse 方法來回BigInteger值,如下列範例所示。

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 {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.
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.

不過,呼叫其他整數型別的方法或包含toBase參數之方法的多載ToStringToString建立的十六進位字串,不會指出衍生十六進位字串的值或源數據類型的正負號。 從這類字串成功具現 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 {0} to {1} and back to {2}.",
                          positiveNumber, hexValue1.Value, positiveBigInt);

        hexString = (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);
    }
}
// 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.