BigInteger構造体は.NET Framework 4より使用できるようになった構造体で、長大な整数を扱うのに便利な多倍長整数型です。 BigIntegerでは扱う値の大きさに合わせて格納領域の割り当てが行われるために扱える値に理論上の上限がなく、Int64やDecimalでは扱えないサイズの整数を扱うことができるようになっています。
なお、BigInteger構造体はアセンブリSystem.Numerics.dllに含まれています。 使用する場合は、System.Numerics.dllへの参照を追加する必要があります。
BigIntegerを使った例
次の例では、Int64とBigIntegerを使って1から30までの階乗を表示しています。 Int64では21!以上の値はオーバーフローするため正しくない結果が表示されていますが、BigIntegerでは正しい値が表示されています。
using System;
using System.Numerics;
class Sample {
static void Main()
{
long lfact = 1L;
BigInteger bifact = 1;
for (int i = 1; i <= 30; i++) {
lfact *= i;
bifact *= i;
Console.WriteLine("{0,2}! = {1,-30} {2,-20}", i, lfact, bifact);
}
}
}
' vbc /removeintchecks+
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim lfact As Long = 1L
DIm bifact As BigInteger = 1
For i As Integer = 1 To 30
lfact *= i
bifact *= i
Console.WriteLine("{0,2}! = {1,-30} {2,-20}", i, lfact, bifact)
Next
End Sub
End Class
1! = 1 1 2! = 2 2 3! = 6 6 4! = 24 24 5! = 120 120 6! = 720 720 7! = 5040 5040 8! = 40320 40320 9! = 362880 362880 10! = 3628800 3628800 11! = 39916800 39916800 12! = 479001600 479001600 13! = 6227020800 6227020800 14! = 87178291200 87178291200 15! = 1307674368000 1307674368000 16! = 20922789888000 20922789888000 17! = 355687428096000 355687428096000 18! = 6402373705728000 6402373705728000 19! = 121645100408832000 121645100408832000 20! = 2432902008176640000 2432902008176640000 21! = -4249290049419214848 51090942171709440000 22! = -1250660718674968576 1124000727777607680000 23! = 8128291617894825984 25852016738884976640000 24! = -7835185981329244160 620448401733239439360000 25! = 7034535277573963776 15511210043330985984000000 26! = -1569523520172457984 403291461126605635584000000 27! = -5483646897237262336 10888869450418352160768000000 28! = -5968160532966932480 304888344611713860501504000000 29! = -7055958792655077376 8841761993739701954543616000000 30! = -8764578968847253504 265252859812191058636308480000000
演算子
BigIntegerには、四則演算・ビット演算・比較演算などの各種演算子が定義されているため、プリミティブな整数型と同じように演算式を記述することができます。
using System;
using System.Numerics;
class Sample {
static void Main()
{
BigInteger x = ulong.MaxValue;
BigInteger y = long.MaxValue;
// 四則演算
Console.WriteLine("{0} + {1} = {2}", x, y, x + y);
Console.WriteLine("{0} - {1} = {2}", x, y, x - y);
Console.WriteLine("{0} * {1} = {2}", x, y, x * y);
Console.WriteLine("{0} / {1} = {2:D4}", x, y, x / y);
// 剰余
Console.WriteLine("{0} % {1} = {2:D2}", x, y, x % y);
// ビットシフト・ビット演算
Console.WriteLine("{0:X} >> 3 = {1:X}", x, x >> 3);
Console.WriteLine("{0:X} << 3 = {1:X}", y, y << 3);
Console.WriteLine("{0:X} ^ 0xffff0000 = {1:X}", x, x ^ 0xffff0000);
// 等値性の比較
if (x == y)
Console.WriteLine("x == y");
else
Console.WriteLine("x != y");
// 大小関係の比較
if (x < int.MaxValue)
Console.WriteLine("x < int.MaxValue");
else
Console.WriteLine("x >= int.MaxValue");
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim x As BigInteger = ULong.MaxValue
Dim y As BigInteger = Long.MaxValue
' 四則演算
Console.WriteLine("{0} + {1} = {2}", x, y, x + y)
Console.WriteLine("{0} - {1} = {2}", x, y, x - y)
Console.WriteLine("{0} * {1} = {2}", x, y, x * y)
Console.WriteLine("{0} / {1} = {2:D4}", x, y, x / y)
' 剰余
Console.WriteLine("{0} % {1} = {2:D2}", x, y, x Mod y)
' ビット演算
Console.WriteLine("{0:X} >> 3 = {1:X}", x, x >> 3)
Console.WriteLine("{0:X} << 3 = {1:X}", y, y << 3)
Console.WriteLine("{0:X} ^ 0xffff0000 = {1:X}", x, x Xor &hFFFF0000)
' 等値性の比較
If x = y Then
Console.WriteLine("x = y")
Else
Console.WriteLine("x <> y")
End If
' 大小関係の比較
If x < Integer.MaxValue Then
Console.WriteLine("x < Integer.MaxValue")
Else
Console.WriteLine("x >= Integer.MaxValue")
End If
End Sub
End Class
18446744073709551615 + 9223372036854775807 = 27670116110564327422 18446744073709551615 - 9223372036854775807 = 9223372036854775808 18446744073709551615 * 9223372036854775807 = 170141183460469231704017187605319778305 18446744073709551615 / 9223372036854775807 = 0002 18446744073709551615 % 9223372036854775807 = 01 0FFFFFFFFFFFFFFFF >> 3 = 1FFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF << 3 = 3FFFFFFFFFFFFFFF8 0FFFFFFFFFFFFFFFF ^ 0xffff0000 = 0FFFFFFFF0000FFFF x != y x >= int.MaxValue
BigIntegerでは、Addメソッド・Multiplyメソッド・Remainderメソッドなど各演算子の代替メソッドも静的メソッドとして用意されているため、これを用いて演算することもできます。 数学関数については、Mathクラスではなく§.数学関数で解説するメソッドを用います。
上記の結果からもわかるとおり、BigIntegerでもD
やX
などの書式指定子がサポートされています。 書式については§.文字列への変換・書式を指定した文字列化 (ToStringメソッド)でも解説します。
また、IComparable<BigInteger>, IEquatable<BigInteger>も実装しているので、BigIntegerの配列をソートしたり、このインターフェースを使用した比較も行えます。
IComparable<T>、IEquatable<T>については大小関係の定義と比較および等価性の定義と比較を参照してください。 ソートについては基本型のソートと昇順・降順でのソートを参照してください。
型変換
数値型との相互変換
BigIntegerでは、Int32などの整数型から/への型変換を行えるようになっています。 整数型へ変換する際、値が型の値域を越えている場合はOverflowExceptionがスローされます。
using System;
using System.Numerics;
class Sample {
static void Main()
{
BigInteger bi = 3;
int i = (int)bi;
Console.WriteLine(i);
bi = long.MaxValue;
i = (int)bi;
Console.WriteLine(i);
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim bi As BigInteger = 3
Dim i As Integer = CInt(bi)
Console.WriteLine(i)
bi = Long.MaxValue
i = CInt(bi)
Console.WriteLine(i)
End Sub
End Class
3 ハンドルされていない例外: System.OverflowException: Int32 型の値が大きすぎるか、または小さすぎます。 場所 System.Numerics.BigInteger.op_Explicit(BigInteger value) 場所 Sample.Main()
また、DoubleやDecimalなどの実数型からの/への変換も同様に行えます。 実数型からBigIntegerに型変換する場合、小数部は切り捨てられます。
using System;
using System.Numerics;
class Sample {
static void Main()
{
BigInteger bi;
bi = (BigInteger)decimal.MaxValue;
Console.WriteLine("{0} => {1}", decimal.MaxValue, bi);
bi = (BigInteger)double.MaxValue;
Console.WriteLine("{0} => {1}", double.MaxValue, bi);
bi = (BigInteger)0.5;
Console.WriteLine("{0} => {1}", 0.5, bi);
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim bi As BigInteger
bi = CType(Decimal.MaxValue, BigInteger)
Console.WriteLine("{0} => {1}", Decimal.MaxValue, bi)
bi = CType(Double.MaxValue, BigInteger)
Console.WriteLine("{0} => {1}", Double.MaxValue, bi)
bi = CType(0.5, BigInteger)
Console.WriteLine("{0} => {1}", 0.5, bi)
End Sub
End Class
79228162514264337593543950335 => 79228162514264337593543950335 1.79769313486232E+308 => 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368 0.5 => 0
Int32, Double, Decimalなどを引数にとるコンストラクタも用意されているので、これを使うこともできます。
using System;
using System.Numerics;
class Sample {
static void Main()
{
Console.WriteLine(new BigInteger(int.MaxValue));
Console.WriteLine(new BigInteger(long.MaxValue));
Console.WriteLine(new BigInteger(float.MaxValue));
Console.WriteLine(new BigInteger(double.MaxValue));
Console.WriteLine(new BigInteger(decimal.MaxValue));
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Console.WriteLine(New BigInteger(Integer.MaxValue))
Console.WriteLine(New BigInteger(Long.MaxValue))
Console.WriteLine(New BigInteger(Single.MaxValue))
Console.WriteLine(New BigInteger(Double.MaxValue))
Console.WriteLine(New BigInteger(Decimal.MaxValue))
End Sub
End Class
2147483647 9223372036854775807 340282346638528859811704183484516925440 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368 79228162514264337593543950335
文字列からの変換 (Parseメソッド・TryParseメソッド)
Parseメソッド、TryParseメソッドも用意されているので、文字列からBigIntegerを生成することもできます。
using System;
using System.Numerics;
class Sample {
static void Main()
{
Console.Write("x? ");
BigInteger x = BigInteger.Parse(Console.ReadLine());
Console.Write("y? ");
BigInteger y = BigInteger.Parse(Console.ReadLine());
Console.WriteLine("x * y = {0}", x * y);
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Console.Write("x? ")
Dim x As BigInteger = BigInteger.Parse(Console.ReadLine())
Console.Write("y? ")
Dim y As BigInteger = BigInteger.Parse(Console.ReadLine())
Console.WriteLine("x * y = {0}", x * y)
End Sub
End Class
x? 10000000000000000000000000000000000000000000000 y? 654654654654987984321324168621357987 x * y = 6546546546549879843213241686213579870000000000000000000000000000000000000000000000
文字列への変換・書式を指定した文字列化 (ToStringメソッド)
ToStringメソッドを使うことでBigIntegerの値を文字列化することができます。 また、引数に書式指定文字列を指定すれば、その書式によって文字列化することもできます。
using System;
using System.Numerics;
class Sample {
static void Main()
{
BigInteger x = BigInteger.Parse("123456789012345678901234567890");
string str = x.ToString(); // ToStringメソッドによる文字列化
Console.WriteLine(str);
Console.WriteLine();
Console.WriteLine(x.ToString("X")); // 16進数形式で文字列化
Console.WriteLine(x.ToString("N0")); // 位取りのカンマを付けて文字列化(小数部は0桁)
Console.WriteLine(x.ToString("E2")); // 指数形式で文字列化(小数部は2桁)
Console.WriteLine();
// 上記のToStringメソッドを使った場合と同じ出力結果となる
Console.WriteLine("{0:X}", x);
Console.WriteLine("{0:N0}", x);
Console.WriteLine("{0:E2}",x);
Console.WriteLine();
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim x As BigInteger = BigInteger.Parse("123456789012345678901234567890")
Dim str As String = x.ToString() ' ToStringメソッドによる文字列化
Console.WriteLine(str)
Console.WriteLine()
Console.WriteLine(x.ToString("X")) ' 16進数形式で文字列化
Console.WriteLine(x.ToString("N0")) ' 位取りのカンマを付けて文字列化(小数部は0桁)
Console.WriteLine(x.ToString("E2")) ' 指数形式で文字列化(小数部は2桁)
Console.WriteLine()
' 上記のToStringメソッドを使った場合と同じ出力結果となる
Console.WriteLine("{0:X}", x)
Console.WriteLine("{0:N0}", x)
Console.WriteLine("{0:E2}",x)
Console.WriteLine()
End Sub
End Class
123456789012345678901234567890 18EE90FF6C373E0EE4E3F0AD2 123,456,789,012,345,678,901,234,567,890 1.23E+029 18EE90FF6C373E0EE4E3F0AD2 123,456,789,012,345,678,901,234,567,890 1.23E+029
この他に使用できる書式指定文字列や、各書式の詳細については書式指定子を参照してください。
バイト配列への変換 (ToByteArrayメソッド)
BigIntegerをバイト配列に変換するには、ToByteArrayメソッドを使うことができます。 得られるバイト配列はリトルエンディアンになります。
using System;
using System.Numerics;
class Sample {
static void Main()
{
BigInteger a = 1;
BigInteger b = -1;
BigInteger c = 256;
BigInteger d = -256;
BigInteger e = 0x12345678;
Console.WriteLine(BitConverter.ToString(a.ToByteArray()));
Console.WriteLine(BitConverter.ToString(b.ToByteArray()));
Console.WriteLine(BitConverter.ToString(c.ToByteArray()));
Console.WriteLine(BitConverter.ToString(d.ToByteArray()));
Console.WriteLine(BitConverter.ToString(e.ToByteArray()));
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim a As BigInteger = 1
Dim b As BigInteger = -1
Dim c As BigInteger = 256
Dim d As BigInteger = -256
Dim e As BigInteger = &h12345678
Console.WriteLine(BitConverter.ToString(a.ToByteArray()))
Console.WriteLine(BitConverter.ToString(b.ToByteArray()))
Console.WriteLine(BitConverter.ToString(c.ToByteArray()))
Console.WriteLine(BitConverter.ToString(d.ToByteArray()))
Console.WriteLine(BitConverter.ToString(e.ToByteArray()))
End Sub
End Class
01 FF 00-01 00-FF 78-56-34-12
また、BigIntegerのコンストラクタはバイト配列を引数にとるバージョンが用意されているので、バイト配列からBigIntegerを構築することもできます。
値の種類
BigIntegerには、格納されている値の種類を知るための次のようなプロパティが用意されています。
- IsZero
- 値が0かどうか。
- IsOne
- 値が1かどうか。
- IsEven
- 値が偶数かどうか。
- IsPowerOfTwo
- 値が2の累乗かどうか。
- Sign
- 値の符号を取得する。 返される値はInt32で、正なら1、負なら-1、0なら0が返される(Math.Signメソッドと同様の動作)
using System;
using System.Numerics;
class Sample {
static void Main()
{
BigInteger bi = 1;
Console.WriteLine(bi);
Console.WriteLine("IsZero : {0}", bi.IsZero);
Console.WriteLine("IsOne : {0}", bi.IsOne);
Console.WriteLine("IsEven : {0}", bi.IsEven);
Console.WriteLine("IsPowerOfTwo : {0}", bi.IsPowerOfTwo);
Console.WriteLine("Sign : {0}", bi.Sign);
Console.WriteLine();
bi = -4;
Console.WriteLine(bi);
Console.WriteLine("IsZero : {0}", bi.IsZero);
Console.WriteLine("IsOne : {0}", bi.IsOne);
Console.WriteLine("IsEven : {0}", bi.IsEven);
Console.WriteLine("IsPowerOfTwo : {0}", bi.IsPowerOfTwo);
Console.WriteLine("Sign : {0}", bi.Sign);
Console.WriteLine();
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim bi As BigInteger = 1
Console.WriteLine(bi)
Console.WriteLine("IsZero : {0}", bi.IsZero)
Console.WriteLine("IsOne : {0}", bi.IsOne)
Console.WriteLine("IsEven : {0}", bi.IsEven)
Console.WriteLine("IsPowerOfTwo : {0}", bi.IsPowerOfTwo)
Console.WriteLine("Sign : {0}", bi.Sign)
Console.WriteLine()
bi = -4
Console.WriteLine(bi)
Console.WriteLine("IsZero : {0}", bi.IsZero)
Console.WriteLine("IsOne : {0}", bi.IsOne)
Console.WriteLine("IsEven : {0}", bi.IsEven)
Console.WriteLine("IsPowerOfTwo : {0}", bi.IsPowerOfTwo)
Console.WriteLine("Sign : {0}", bi.Sign)
Console.WriteLine()
End Sub
End Class
1 IsZero : False IsOne : True IsEven : False IsPowerOfTwo : True Sign : 1 -4 IsZero : False IsOne : False IsEven : True IsPowerOfTwo : False Sign : -1
なお、0
、+1
、-1
の三値に相当する定数は静的プロパティとして用意されています。
using System;
using System.Numerics;
class Sample {
static void Main()
{
Console.WriteLine(BigInteger.Zero);
Console.WriteLine(BigInteger.One);
Console.WriteLine(BigInteger.MinusOne);
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Console.WriteLine(BigInteger.Zero)
Console.WriteLine(BigInteger.One)
Console.WriteLine(BigInteger.MinusOne)
End Sub
End Class
0 1 -1
数学関数
Mathクラスに用意されている数学関数は、BigIntegerをサポートしていません。 代わりに、これらの関数はBigInteger構造体のメソッドとして提供されています。 BigIntegerには次のようなメソッドが用意されています。 Mathクラスと同様、いずれも静的メソッドです。
関数 | BigIntegerのメソッド | 相当するMathクラスのメソッド |
---|---|---|
絶対値 |x| | BigInteger.Abs(x) | Math.Abs |
最大 max(x, y) | BigInteger.Max(x, y) | Math.Max |
最小 min(x, y) | BigInteger.Min(x, y) | Math.Min |
商と剰余 | BigInteger.DivRem(x, y, out remainder) | Math.DivRem |
累乗 xn | BigInteger.Pow(x, n) | Math.Pow |
自然対数 ln x | BigInteger.Log(x) | Math.Log |
常用対数 log10x | BigInteger.Log10(x) | Math.Log10 |
対数 logax | BigInteger.Log(x, a) | Math.Log |
関数 | BigIntegerのメソッド | 相当するMathクラスのメソッド |
次の例では、BigIntegerを使って5以上の階乗の値を求め、BigInteger.Log10メソッドでの桁数を求めて指数表記で表示しています。
using System;
using System.Numerics;
class Sample {
static void Main()
{
BigInteger fact = BigInteger.One;
for (int i = 1; i <= 30; i++) {
fact *= i;
if (i < 5)
continue;
int exp = (int)BigInteger.Log10(fact);
double mant = (double)fact / Math.Pow(10, exp);
Console.WriteLine("{0,2}! = {1,35} ≒ {2:F2} x 10^{3}", i, fact, mant, exp);
}
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim fact As BigInteger = BigInteger.One
For i As Integer = 1 To 30
fact *= i
If i < 5 Then Continue For
Dim exp As Integer = CInt(Math.Truncate(BigInteger.Log10(fact)))
Dim mant As Double = CDbl(fact) / Math.Pow(10, exp)
Console.WriteLine("{0,2}! = {1,35} ≒ {2:F2} x 10^{3}", i, fact, mant, exp)
Next
End Sub
End Class
5! = 120 ≒ 1.20 x 10^2 6! = 720 ≒ 7.20 x 10^2 7! = 5040 ≒ 5.04 x 10^3 8! = 40320 ≒ 4.03 x 10^4 9! = 362880 ≒ 3.63 x 10^5 10! = 3628800 ≒ 3.63 x 10^6 11! = 39916800 ≒ 3.99 x 10^7 12! = 479001600 ≒ 4.79 x 10^8 13! = 6227020800 ≒ 6.23 x 10^9 14! = 87178291200 ≒ 8.72 x 10^10 15! = 1307674368000 ≒ 1.31 x 10^12 16! = 20922789888000 ≒ 2.09 x 10^13 17! = 355687428096000 ≒ 3.56 x 10^14 18! = 6402373705728000 ≒ 6.40 x 10^15 19! = 121645100408832000 ≒ 1.22 x 10^17 20! = 2432902008176640000 ≒ 2.43 x 10^18 21! = 51090942171709440000 ≒ 5.11 x 10^19 22! = 1124000727777607680000 ≒ 1.12 x 10^21 23! = 25852016738884976640000 ≒ 2.59 x 10^22 24! = 620448401733239439360000 ≒ 6.20 x 10^23 25! = 15511210043330985984000000 ≒ 1.55 x 10^25 26! = 403291461126605635584000000 ≒ 4.03 x 10^26 27! = 10888869450418352160768000000 ≒ 1.09 x 10^28 28! = 304888344611713860501504000000 ≒ 3.05 x 10^29 29! = 8841761993739701954543616000000 ≒ 8.84 x 10^30 30! = 265252859812191058636308480000000 ≒ 2.65 x 10^32
また、Mathクラスでは提供されない、次のようなメソッドも用意されています。
- BigInteger.ModPow(value, exponent, modulus)
- 次の式で得られる剰余を求めます。 valueexponent mod modulus
- BigInteger.GreatestCommonDivisor(x, y)
- xとyの最大公約数を求めます。
一方で、java.math.BigIntegerにあるようなmodInverseやnextProbablePrimeなどのメソッドは用意されていません。
乱数
BigIntegerには乱数を生成するためのメソッドが用意されておらず、またRandomクラスもBigIntegerに対応したメソッドを持っていません。 ここではBigIntegerの乱数を生成する方法について見ていきます。 なお、以下で紹介する方法では乱数の分布等についてはあまり考慮していません。 必要とする乱数の性質に合わせて適切な方法を選んでください。
乱数の生成方法については乱数を参照してください。
Random.NextDoubleを使う方法
BigIntegerの乱数を生成する方法にはいくつかありますが、その一つはRandom.NextDoubleメソッドを使う方法です。 次の例では、0からdouble.MaxValueまで範囲にある乱数を生成し、BigIntegerに変換しています。
using System;
using System.Numerics;
class Sample {
static void Main()
{
Random rand = new Random();
for (int i = 0; i < 10; i++) {
// 0からdouble.MaxValueまでの乱数を取得
BigInteger val = new BigInteger(double.MaxValue * rand.NextDouble());
Console.WriteLine("[{0}]: {1}", i, val);
}
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim rand As New Random()
For i As Integer = 0 To 9
' 0からDouble.MaxValueまでの乱数を取得
Dim val As New BigInteger(Double.MaxValue * rand.NextDouble())
Console.WriteLine("[{0}]: {1}", i, val)
Next
End Sub
End Class
[0]: 82098446065070156516008802208350072595314490504383488226990961977787093047512140228093296480588178848469182561244964693041601173558405848200725641188829553108217990062488995508471544291415749956295518073463357320003663833826358242419565362873425908071347196595471358469790860472070847389936409494669924237312 [1]: 159125106373833346888532116689178334185657037814698423494728732570490746875483848344797628103533988226348482728319141435706353646357712486582459088857906478848545811431392960994837354761263410723727062325450499879493329249862292564793610297868794881622382709294561067589043126240854751956620733729372167471104 [2]: 24425720459536395152412038673807295575020179457090129721418108438287180595278942282501621674304698909238977042972079615458528444698133177003978247965412513167424660497083840452587276273159791713546889603430336011958702818045071534581470550998582848022666054172810878317028414869986145334178944543332870651904 [3]: 116145450336362985322687072923306552635209274725327595812798074610837754724245153732291513822014103387542666401940898652792372336254853042114641587938076825197646705911630900221013318847296239357389764552923994602798932229382507820329873388835959152161933624167406904293894522727069866761988978094956494192640 [4]: 49430656114312776445829286722055949684073078963672663539980136807928486937699000065259145886798929660861514948291688428334441800765644979225387796440292297985266714042378489546850911315108287121513772387748103167223629322251155799576341618400954150131582561750389927568383735715502301617974957898754569535488 [5]: 163599062235324911493059876946008993511653214156530575475754606311835559435176571000548681910245808956085828572605735178662664230429391826797760090184505486371950528387960787696124274403094445676866307057063610622681275573504099893042861144771632185237204906003096001565855248032952609108871593267426649702400 [6]: 61720759976511630651119394955525127126046450840236557828065111095558514067734349681081047277471532939032994355164935986363251541221595232384773682138291443254855982960682776962708941980027548303665427306979388059844885026921576482873926448840374801634113333566489452019283760265316368390937133046254652096512 [7]: 30944481736189514555142738234766880263850378772289569292548359843626090069647422772083415974386957307872063790993553412474979526128120612471907738764647993662850837966354889662312021086851702538291948450483958854384539224460165152448832701160046792341017136619872837616960743493592210136313036920845615759360 [8]: 114457505589159584483391492407454148689000893814980965243936074425962377575702722752748083790255375940479840957095888453749181796494929653948668916029536164048158677779493168926630391332505423943593071414407215232973926609732320185704087100868948222057173797499054080854238817571324601192681123739542812098560 [9]: 8906766378429304742952410713253696387604315959790377223244985228593224411910979463047355000651563290868461657390730221957146068138908950521229627159015232016362709301711496986882807866327296855232372596843424489557156651722736719987923455411213918681582858639709767273735697029785048400915841843483048411136
ただ、この方法ではdoubleで扱える範囲を越える大きさの乱数は生成出来ません。
Random.NextBytesを使う方法
もう一つの方法は、Random.NextBytesメソッドを使い、ランダムなビット列からBigIntegerを生成する方法です。 次の例では、0からdouble.MaxValueまで範囲にある乱数を生成し、BigIntegerに変換しています。
using System;
using System.Numerics;
class Sample {
static void Main()
{
Random rand = new Random();
for (int i = 0; i < 10; i++) {
// 256ビットのランダムなビット列を生成
byte[] bits = new byte[32];
rand.NextBytes(bits);
// BigIntegerに変換
BigInteger val = new BigInteger(bits);
Console.WriteLine("[{0}]: {1}", i, val);
}
}
}
Imports System
Imports System.Numerics
Class Sample
Shared Sub Main()
Dim rand As New Random()
For i As Integer = 0 To 9
' 256ビットのランダムなビット列を生成
Dim bits(32) As Byte
rand.NextBytes(bits)
' BigIntegerに変換
Dim val As New BigInteger(bits)
Console.WriteLine("[{0}]: {1}", i, val)
Next
End Sub
End Class
[0]: 31028064291330346535026151635948079032369095082522834739863768437340236011080 [1]: -32550629667785318791696806315870094803545391250044371755888339672469526542675 [2]: 49815678509557472543873841157391969859324679847740358083506639519357644099320 [3]: 630672323019855186579551760740076366310457726309894294288548170790741117496 [4]: 29651103186920854548601632349177911836778182541697080309367692088137977284847 [5]: 16721155174693624114029016175151806942420375366831651736724778061290505342388 [6]: -8922837380470792087125118174969304135093453973569613283227323991664307969189 [7]: -48049234631178771981897607151534592721235468994417322257552687131763732758467 [8]: -27469885429035582987573376251452946234900188759372637407352222278483271783966 [9]: 11048698812527087192810912551820310151129964162681509215288805296886479828894
この方法では任意のビット数の乱数を生成できますが、Random.Nextメソッドのように上限・下限を指定したり、桁数を限定して生成することは出来ません。
文字列から生成する方法
また別の方法として、文字列を使う方法があげられます。 次の例では、100桁の乱数をまず文字列として生成し、その後BigIntegerに変換しています。
using System;
using System.Numerics;
using System.Text;
class Sample {
static void Main()
{
Random rand = new Random();
for (int i = 0; i < 10; i++) {
StringBuilder numbers = new StringBuilder();
// 100桁のランダムな数値を表す文字列を生成
for (int n = 0; n < 100; n++) {
numbers.Append(rand.Next(0, 10).ToString());
}
// BigIntegerに変換
BigInteger val = BigInteger.Parse(numbers.ToString());
Console.WriteLine("[{0}]: {1}", i, val);
}
}
}
Imports System
Imports System.Numerics
Imports System.Text
Class Sample
Shared Sub Main()
Dim rand As New Random()
For i As Integer = 0 To 9
Dim numbers As New StringBuilder()
' 100桁のランダムな数値を表す文字列を生成
For n As Integer = 0 To 99
numbers.Append(rand.Next(0, 10).ToString())
Next
' BigIntegerに変換
Dim val As BigInteger = BigInteger.Parse(numbers.ToString())
Console.WriteLine("[{0}]: {1}", i, val)
Next
End Sub
End Class
[0]: 252978269964842522533362568346227577040488410026817394808729876518963136345031447115745238731811405 [1]: 602435246356331567404902434909795191773288734828377495375141851456809328362994977358128063377009511 [2]: 4978604904194418171351685449657080873830046701682550863307087650362749124575305137978158725534880195 [3]: 8621280072810731212550781593294223217147836164852287801539801960345819378978177529428562976805415748 [4]: 2077082625909042816198436291986451610475656787378124751745088896934226812595091883000858227710643183 [5]: 6450283743252710680403390361211347620290168824320281871307498074156456638758467638722069506673388033 [6]: 753903640711332341375116984854726926480728230456494288248464973253993777742333440010409349644394170 [7]: 6122993073254977520302197555749369295042979037457739321352093364446350305291897403481661573243982612 [8]: 8573704515637261824529231731586372766119747953911150125474504231716772160202897798644406569848813482 [9]: 5944263781419806853572947116038015288738552987991697344489148630699003793759840232465271838770151538