Random クラス

定義

擬似乱数ジェネレーターを表します。これは、乱数についての特定の統計的な要件を満たす数値系列を生成するアルゴリズムです。

public ref class Random
public class Random
[System.Serializable]
public class Random
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class Random
type Random = class
[<System.Serializable>]
type Random = class
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type Random = class
Public Class Random
継承
Random
属性

次の例では、1 つの乱数ジェネレーターを作成し、その NextBytesNext、および NextDouble メソッドを呼び出して、異なる範囲内の乱数のシーケンスを生成します。

using namespace System;

void main()
{
   // Instantiate random number generator using system-supplied value as seed.
   Random^ rand = gcnew Random();
   // Generate and display 5 random byte (integer) values.
   array<Byte>^ bytes = gcnew array<Byte>(4);
   rand->NextBytes(bytes);
   Console::WriteLine("Five random byte values:");
   for each (Byte byteValue in bytes)
      Console::Write("{0, 5}", byteValue);
   Console::WriteLine();
   // Generate and display 5 random integers.
   Console::WriteLine("Five random integer values:");
   for (int ctr = 0; ctr <= 4; ctr++)
      Console::Write("{0,15:N0}", rand->Next());
   Console::WriteLine();
   // Generate and display 5 random integers between 0 and 100.//
   Console::WriteLine("Five random integers between 0 and 100:");
   for (int ctr = 0; ctr <= 4; ctr++)
      Console::Write("{0,8:N0}", rand->Next(101));
   Console::WriteLine();
   // Generate and display 5 random integers from 50 to 100.
   Console::WriteLine("Five random integers between 50 and 100:");
   for (int ctr = 0; ctr <= 4; ctr++)
      Console::Write("{0,8:N0}", rand->Next(50, 101));
   Console::WriteLine();
   // Generate and display 5 random floating point values from 0 to 1.
   Console::WriteLine("Five Doubles.");
   for (int ctr = 0; ctr <= 4; ctr++)
      Console::Write("{0,8:N3}", rand->NextDouble());
   Console::WriteLine();
   // Generate and display 5 random floating point values from 0 to 5.
   Console::WriteLine("Five Doubles between 0 and 5.");
   for (int ctr = 0; ctr <= 4; ctr++)
      Console::Write("{0,8:N3}", rand->NextDouble() * 5);
}
// The example displays output like the following:
//    Five random byte values:
//      194  185  239   54  116
//    Five random integer values:
//        507,353,531  1,509,532,693  2,125,074,958  1,409,512,757    652,767,128
//    Five random integers between 0 and 100:
//          16      78      94      79      52
//    Five random integers between 50 and 100:
//          56      66      96      60      65
//    Five Doubles.
//       0.943   0.108   0.744   0.563   0.415
//    Five Doubles between 0 and 5.
//       2.934   3.130   0.292   1.432   4.369
// Instantiate random number generator using system-supplied value as seed.
var rand = new Random();

// Generate and display 5 random byte (integer) values.
var bytes = new byte[5];
rand.NextBytes(bytes);
Console.WriteLine("Five random byte values:");
foreach (byte byteValue in bytes)
    Console.Write("{0, 5}", byteValue);
Console.WriteLine();

// Generate and display 5 random integers.
Console.WriteLine("Five random integer values:");
for (int ctr = 0; ctr <= 4; ctr++)
    Console.Write("{0,15:N0}", rand.Next());
Console.WriteLine();

// Generate and display 5 random integers between 0 and 100.
Console.WriteLine("Five random integers between 0 and 100:");
for (int ctr = 0; ctr <= 4; ctr++)
    Console.Write("{0,8:N0}", rand.Next(101));
Console.WriteLine();

// Generate and display 5 random integers from 50 to 100.
Console.WriteLine("Five random integers between 50 and 100:");
for (int ctr = 0; ctr <= 4; ctr++)
    Console.Write("{0,8:N0}", rand.Next(50, 101));
Console.WriteLine();

// Generate and display 5 random floating point values from 0 to 1.
Console.WriteLine("Five Doubles.");
for (int ctr = 0; ctr <= 4; ctr++)
    Console.Write("{0,8:N3}", rand.NextDouble());
Console.WriteLine();

// Generate and display 5 random floating point values from 0 to 5.
Console.WriteLine("Five Doubles between 0 and 5.");
for (int ctr = 0; ctr <= 4; ctr++)
    Console.Write("{0,8:N3}", rand.NextDouble() * 5);

// The example displays output like the following:
//    Five random byte values:
//      194  185  239   54  116
//    Five random integer values:
//        507,353,531  1,509,532,693  2,125,074,958  1,409,512,757    652,767,128
//    Five random integers between 0 and 100:
//          16      78      94      79      52
//    Five random integers between 50 and 100:
//          56      66      96      60      65
//    Five Doubles.
//       0.943   0.108   0.744   0.563   0.415
//    Five Doubles between 0 and 5.
//       2.934   3.130   0.292   1.432   4.369
// Instantiate random number generator using system-supplied value as seed.
let rand = Random()

// Generate and display 5 random byte (integer) values.
let bytes = Array.zeroCreate 5
rand.NextBytes bytes
printfn "Five random byte values:"
for byte in bytes do
    printf "%5i" byte
printfn ""

// Generate and display 5 random integers.
printfn "Five random integer values:"
for _ = 0 to 4 do
    printf $"{rand.Next(),15:N0}" 
printfn ""

// Generate and display 5 random integers between 0 and 100.
printfn "Five random integers between 0 and 100:"
for _ = 0 to 4 do
    printf $"{rand.Next 101,8:N0}"
printfn ""

// Generate and display 5 random integers from 50 to 100.
printfn "Five random integers between 50 and 100:"
for _ = 0 to 4 do
    printf $"{rand.Next(50, 101),8:N0}"
printfn ""

// Generate and display 5 random floating point values from 0 to 1.
printfn "Five Doubles."
for _ = 0 to 4 do
    printf $"{rand.NextDouble(),8:N3}"
printfn ""

// Generate and display 5 random floating point values from 0 to 5.
printfn "Five Doubles between 0 and 5."
for _ = 0 to 4 do
    printf $"{rand.NextDouble() * 5.0,8:N3}"

// The example displays output like the following:
//    Five random byte values:
//      194  185  239   54  116
//    Five random integer values:
//        507,353,531  1,509,532,693  2,125,074,958  1,409,512,757    652,767,128
//    Five random integers between 0 and 100:
//          16      78      94      79      52
//    Five random integers between 50 and 100:
//          56      66      96      60      65
//    Five Doubles.
//       0.943   0.108   0.744   0.563   0.415
//    Five Doubles between 0 and 5.
//       2.934   3.130   0.292   1.432   4.369
Module Example
   Public Sub Main()
      ' Instantiate random number generator using system-supplied value as seed.
      Dim rand As New Random()
      ' Generate and display 5 random byte (integer) values.
      Dim bytes(4) As Byte
      rand.NextBytes(bytes)
      Console.WriteLine("Five random byte values:")
      For Each byteValue As Byte In bytes
         Console.Write("{0, 5}", byteValue)
      Next
      Console.WriteLine()   
      ' Generate and display 5 random integers.
      Console.WriteLine("Five random integer values:")
      For ctr As Integer = 0 To 4
         Console.Write("{0,15:N0}", rand.Next)
      Next                     
      Console.WriteLine()
      ' Generate and display 5 random integers between 0 and 100.'
      Console.WriteLine("Five random integers between 0 and 100:")
      For ctr As Integer = 0 To 4
         Console.Write("{0,8:N0}", rand.Next(101))
      Next                     
      Console.WriteLine()
      ' Generate and display 5 random integers from 50 to 100.
      Console.WriteLine("Five random integers between 50 and 100:")
      For ctr As Integer = 0 To 4
         Console.Write("{0,8:N0}", rand.Next(50, 101))
      Next                     
      Console.WriteLine()
      ' Generate and display 5 random floating point values from 0 to 1.
      Console.WriteLine("Five Doubles.")
      For ctr As Integer = 0 To 4
         Console.Write("{0,8:N3}", rand.NextDouble())
      Next                     
      Console.WriteLine()
      ' Generate and display 5 random floating point values from 0 to 5.
      Console.WriteLine("Five Doubles between 0 and 5.")
      For ctr As Integer = 0 To 4
         Console.Write("{0,8:N3}", rand.NextDouble() * 5)
      Next                     
   End Sub
End Module
' The example displays output like the following:
'    Five random byte values:
'      194  185  239   54  116
'    Five random integer values:
'        507,353,531  1,509,532,693  2,125,074,958  1,409,512,757    652,767,128
'    Five random integers between 0 and 100:
'          16      78      94      79      52
'    Five random integers between 50 and 100:
'          56      66      96      60      65
'    Five Doubles.
'       0.943   0.108   0.744   0.563   0.415
'    Five Doubles between 0 and 5.
'       2.934   3.130   0.292   1.432   4.369

次の例では、配列から文字列値を取得するためのインデックスとして使用するランダムな整数を生成します。

using namespace System;

void main()
{
   Random^ rnd = gcnew Random();
   array<String^>^ malePetNames = { "Rufus", "Bear", "Dakota", "Fido",
                                    "Vanya", "Samuel", "Koani", "Volodya",
                                    "Prince", "Yiska" };
   array<String^>^ femalePetNames = { "Maggie", "Penny", "Saya", "Princess",
                                      "Abby", "Laila", "Sadie", "Olivia",
                                      "Starlight", "Talla" };
      
   // Generate random indexes for pet names.
   int mIndex = rnd->Next(malePetNames->Length);
   int fIndex = rnd->Next(femalePetNames->Length);
      
   // Display the result.
   Console::WriteLine("Suggested pet name of the day: ");
   Console::WriteLine("   For a male:     {0}", malePetNames[mIndex]);
   Console::WriteLine("   For a female:   {0}", femalePetNames[fIndex]);
}
// The example displays output similar to the following:
//       Suggested pet name of the day:
//          For a male:     Koani
//          For a female:   Maggie
Random rnd = new Random();
string[] malePetNames = { "Rufus", "Bear", "Dakota", "Fido",
                          "Vanya", "Samuel", "Koani", "Volodya",
                          "Prince", "Yiska" };
string[] femalePetNames = { "Maggie", "Penny", "Saya", "Princess",
                            "Abby", "Laila", "Sadie", "Olivia",
                            "Starlight", "Talla" };

// Generate random indexes for pet names.
int mIndex = rnd.Next(malePetNames.Length);
int fIndex = rnd.Next(femalePetNames.Length);

// Display the result.
Console.WriteLine("Suggested pet name of the day: ");
Console.WriteLine("   For a male:     {0}", malePetNames[mIndex]);
Console.WriteLine("   For a female:   {0}", femalePetNames[fIndex]);

// The example displays output similar to the following:
//       Suggested pet name of the day:
//          For a male:     Koani
//          For a female:   Maggie
let rnd = Random()

let malePetNames =
    [| "Rufus"; "Bear"; "Dakota"; "Fido";
        "Vanya"; "Samuel"; "Koani"; "Volodya";
        "Prince"; "Yiska" |]
let femalePetNames = 
    [| "Maggie"; "Penny"; "Saya"; "Princess";
        "Abby"; "Laila"; "Sadie"; "Olivia";
        "Starlight"; "Talla" |]

// Generate random indexes for pet names.
let mIndex = rnd.Next malePetNames.Length
let fIndex = rnd.Next femalePetNames.Length

// Display the result.
printfn "Suggested pet name of the day: "
printfn "   For a male:     %s" malePetNames.[mIndex]
printfn "   For a female:   %s" femalePetNames.[fIndex]

// The example displays output similar to the following:
//       Suggested pet name of the day:
//          For a male:     Koani
//          For a female:   Maggie
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      Dim malePetNames() As String = { "Rufus", "Bear", "Dakota", "Fido", 
                                    "Vanya", "Samuel", "Koani", "Volodya", 
                                    "Prince", "Yiska" }
      Dim femalePetNames() As String = { "Maggie", "Penny", "Saya", "Princess", 
                                         "Abby", "Laila", "Sadie", "Olivia", 
                                         "Starlight", "Talla" }                                      
      
      ' Generate random indexes for pet names.
      Dim mIndex As Integer = rnd.Next(malePetNames.Length)
      Dim fIndex As Integer = rnd.Next(femalePetNames.Length)
      
      ' Display the result.
      Console.WriteLine("Suggested pet name of the day: ")
      Console.WriteLine("   For a male:     {0}", malePetNames(mIndex))
      Console.WriteLine("   For a female:   {0}", femalePetNames(fIndex))
   End Sub
End Module
' The example displays output similar to the following:
'       Suggested pet name of the day:
'          For a male:     Koani
'          For a female:   Maggie

注釈

擬似乱数は、有限の数値セットから等しい確率で選択されます。 数学的アルゴリズムはそれらを選択するために使用されますが、実用的な目的のために十分にランダムであるため、選択された数値は完全にランダムではありません。 クラスの現在の Random 実装は、Donald E. Knuth の減算乱数ジェネレーター アルゴリズムの変更されたバージョンに基づいています。 詳細については、「D. E. Knuth」を参照してください。 コンピューター プログラミングの技術、第 2 巻: 半数値アルゴリズム。 1997 年、Addison-Wesley、Reading、MA、第 3 版。

ランダム なパスワードの作成に適した乱数など、暗号で保護された乱数を生成するには、 クラスを RNGCryptoServiceProvider 使用するか、 から System.Security.Cryptography.RandomNumberGeneratorクラスを派生させます。

このトピックの内容:

乱数ジェネレーターのインスタンス化
複数のインスタンス化を回避する
System.Random クラスとスレッド セーフ
さまざまな種類の乱数の生成
独自のアルゴリズムを置き換え
System.Random to... を使用する方法
ランダム値の同じシーケンスを取得する
ランダム値の一意のシーケンスを取得する
指定した範囲内の整数を取得する
指定した桁数の整数を取得する
指定した範囲内の浮動小数点値を取得する
ランダムなブール値を生成する
ランダムな 64 ビット整数を生成する
指定した範囲内のバイトを取得する
配列またはコレクションからランダムに要素を取得する
配列またはコレクションから一意の要素を取得する

乱数ジェネレーターのインスタンス化

乱数ジェネレーターをインスタンス化するには、シード値 (擬似乱数生成アルゴリズムの開始値) をクラス コンストラクターに Random 提供します。 シード値は、明示的または暗黙的に指定できます。

  • コンストラクターは Random(Int32) 、指定した明示的なシード値を使用します。

  • コンストラクターは Random() 、既定のシード値を使用します。 これは、乱数ジェネレーターをインスタンス化する最も一般的な方法です。

.NET Frameworkでは、既定のシード値は時間に依存します。 .NET Core では、既定のシード値は、スレッド静的擬似乱数ジェネレーターによって生成されます。

同じシードを別々 Random のオブジェクトに使用すると、同じ一連の乱数が生成されます。 これは、ランダムな値を処理するテスト スイートを作成したり、乱数からデータを派生させるゲームを再生したりする場合に便利です。 ただし、異なるバージョンの.NET Frameworkで実行されているプロセス内のオブジェクトは、同じシード値でインスタンス化されている場合でも、異なる一連の乱数を返す可能性があることに注意Randomしてください。

乱数の異なるシーケンスを生成するには、シード値を時間に依存させ、それによって の新しいインスタンス Randomごとに異なる系列を生成できます。 パラメーター化された Random(Int32) コンストラクターは、現在の時刻のティック数に基づいて値を受け取ることができます Int32 。一方、パラメーターなしの Random() コンストラクターはシステム クロックを使用してそのシード値を生成します。 ただし、.NET Frameworkでのみ、クロックには有限の解像度があるため、パラメーターなしのコンストラクターを使用して異なるRandomオブジェクトを連続して作成すると、同じ乱数シーケンスを生成する乱数ジェネレーターが作成されます。 次の例は、.NET Framework アプリケーションで連続してインスタンス化された 2 つのRandomオブジェクトが、同じ一連の乱数を生成する方法を示しています。 ほとんどの Windows システムでは、 Random 互いに 15 ミリ秒以内に作成されたオブジェクトのシード値が同じである可能性があります。

using namespace System;

void main()
{
   array<Byte>^ bytes1 = gcnew array<Byte>(100);
   array<Byte>^ bytes2 = gcnew array<Byte>(100);
   Random^ rnd1 = gcnew Random();
   Random^ rnd2 = gcnew Random();
   
   rnd1->NextBytes(bytes1);
   rnd2->NextBytes(bytes2);
   
   Console::WriteLine("First Series:");
   for (int ctr = bytes1->GetLowerBound(0);
        ctr <= bytes1->GetUpperBound(0);
        ctr++) { 
      Console::Write("{0, 5}", bytes1[ctr]);
      if ((ctr + 1) % 10 == 0) Console::WriteLine();
   } 
   Console::WriteLine();
   Console::WriteLine("Second Series:");
   for (int ctr = bytes2->GetLowerBound(0);
        ctr <= bytes2->GetUpperBound(0);
        ctr++) {
      Console::Write("{0, 5}", bytes2[ctr]);
      if ((ctr + 1) % 10 == 0) Console::WriteLine();
   }   
}
// The example displays output like the following:
//       First Series:
//          97  129  149   54   22  208  120  105   68  177
//         113  214   30  172   74  218  116  230   89   18
//          12  112  130  105  116  180  190  200  187  120
//           7  198  233  158   58   51   50  170   98   23
//          21    1  113   74  146  245   34  255   96   24
//         232  255   23    9  167  240  255   44  194   98
//          18  175  173  204  169  171  236  127  114   23
//         167  202  132   65  253   11  254   56  214  127
//         145  191  104  163  143    7  174  224  247   73
//          52    6  231  255    5  101   83  165  160  231
//       
//       Second Series:
//          97  129  149   54   22  208  120  105   68  177
//         113  214   30  172   74  218  116  230   89   18
//          12  112  130  105  116  180  190  200  187  120
//           7  198  233  158   58   51   50  170   98   23
//          21    1  113   74  146  245   34  255   96   24
//         232  255   23    9  167  240  255   44  194   98
//          18  175  173  204  169  171  236  127  114   23
//         167  202  132   65  253   11  254   56  214  127
//         145  191  104  163  143    7  174  224  247   73
//          52    6  231  255    5  101   83  165  160  231
byte[] bytes1 = new byte[100];
byte[] bytes2 = new byte[100];
Random rnd1 = new Random();
Random rnd2 = new Random();

rnd1.NextBytes(bytes1);
rnd2.NextBytes(bytes2);

Console.WriteLine("First Series:");
for (int ctr = bytes1.GetLowerBound(0);
     ctr <= bytes1.GetUpperBound(0);
     ctr++) {
   Console.Write("{0, 5}", bytes1[ctr]);
   if ((ctr + 1) % 10 == 0) Console.WriteLine();
}

Console.WriteLine();

Console.WriteLine("Second Series:");
for (int ctr = bytes2.GetLowerBound(0);
     ctr <= bytes2.GetUpperBound(0);
     ctr++) {
   Console.Write("{0, 5}", bytes2[ctr]);
   if ((ctr + 1) % 10 == 0) Console.WriteLine();
}

// The example displays output like the following:
//       First Series:
//          97  129  149   54   22  208  120  105   68  177
//         113  214   30  172   74  218  116  230   89   18
//          12  112  130  105  116  180  190  200  187  120
//           7  198  233  158   58   51   50  170   98   23
//          21    1  113   74  146  245   34  255   96   24
//         232  255   23    9  167  240  255   44  194   98
//          18  175  173  204  169  171  236  127  114   23
//         167  202  132   65  253   11  254   56  214  127
//         145  191  104  163  143    7  174  224  247   73
//          52    6  231  255    5  101   83  165  160  231
//
//       Second Series:
//          97  129  149   54   22  208  120  105   68  177
//         113  214   30  172   74  218  116  230   89   18
//          12  112  130  105  116  180  190  200  187  120
//           7  198  233  158   58   51   50  170   98   23
//          21    1  113   74  146  245   34  255   96   24
//         232  255   23    9  167  240  255   44  194   98
//          18  175  173  204  169  171  236  127  114   23
//         167  202  132   65  253   11  254   56  214  127
//         145  191  104  163  143    7  174  224  247   73
//          52    6  231  255    5  101   83  165  160  231
let bytes1 = Array.zeroCreate 100
let bytes2 = Array.zeroCreate 100
let rnd1 = Random()
let rnd2 = Random()

rnd1.NextBytes bytes1 
rnd2.NextBytes bytes2 

printfn "First Series"
for i = bytes1.GetLowerBound 0 to bytes1.GetUpperBound 0 do
    printf "%5i" bytes1.[i]
    if (i + 1) % 10 = 0 then printfn ""

printfn ""

printfn "Second Series"
for i = bytes2.GetLowerBound 0 to bytes2.GetUpperBound 0 do
    printf "%5i" bytes2.[i]
    if (i + 1) % 10 = 0 then printfn ""

// The example displays output like the following:
//       First Series:
//          97  129  149   54   22  208  120  105   68  177
//         113  214   30  172   74  218  116  230   89   18
//          12  112  130  105  116  180  190  200  187  120
//           7  198  233  158   58   51   50  170   98   23
//          21    1  113   74  146  245   34  255   96   24
//         232  255   23    9  167  240  255   44  194   98
//          18  175  173  204  169  171  236  127  114   23
//         167  202  132   65  253   11  254   56  214  127
//         145  191  104  163  143    7  174  224  247   73
//          52    6  231  255    5  101   83  165  160  231
//
//       Second Series:
//          97  129  149   54   22  208  120  105   68  177
//         113  214   30  172   74  218  116  230   89   18
//          12  112  130  105  116  180  190  200  187  120
//           7  198  233  158   58   51   50  170   98   23
//          21    1  113   74  146  245   34  255   96   24
//         232  255   23    9  167  240  255   44  194   98
//          18  175  173  204  169  171  236  127  114   23
//         167  202  132   65  253   11  254   56  214  127
//         145  191  104  163  143    7  174  224  247   73
//          52    6  231  255    5  101   83  165  160  231
Module modMain

   Public Sub Main()
      Dim bytes1(99), bytes2(99) As Byte
      Dim rnd1 As New Random()
      Dim rnd2 As New Random()
      
      rnd1.NextBytes(bytes1)
      rnd2.NextBytes(bytes2)
      
      Console.WriteLine("First Series:")
      For ctr As Integer = bytes1.GetLowerBound(0) to bytes1.GetUpperBound(0)
         Console.Write("{0, 5}", bytes1(ctr))
         If (ctr + 1) Mod 10 = 0 Then Console.WriteLine()
      Next 
      Console.WriteLine()
      Console.WriteLine("Second Series:")        
      For ctr As Integer = bytes2.GetLowerBound(0) to bytes2.GetUpperBound(0)
         Console.Write("{0, 5}", bytes2(ctr))
         If (ctr + 1) Mod 10 = 0 Then Console.WriteLine()
      Next   
   End Sub
End Module
' The example displays output like the following:
'       First Series:
'          97  129  149   54   22  208  120  105   68  177
'         113  214   30  172   74  218  116  230   89   18
'          12  112  130  105  116  180  190  200  187  120
'           7  198  233  158   58   51   50  170   98   23
'          21    1  113   74  146  245   34  255   96   24
'         232  255   23    9  167  240  255   44  194   98
'          18  175  173  204  169  171  236  127  114   23
'         167  202  132   65  253   11  254   56  214  127
'         145  191  104  163  143    7  174  224  247   73
'          52    6  231  255    5  101   83  165  160  231
'       
'       Second Series:
'          97  129  149   54   22  208  120  105   68  177
'         113  214   30  172   74  218  116  230   89   18
'          12  112  130  105  116  180  190  200  187  120
'           7  198  233  158   58   51   50  170   98   23
'          21    1  113   74  146  245   34  255   96   24
'         232  255   23    9  167  240  255   44  194   98
'          18  175  173  204  169  171  236  127  114   23
'         167  202  132   65  253   11  254   56  214  127
'         145  191  104  163  143    7  174  224  247   73
'          52    6  231  255    5  101   83  165  160  231

この問題を回避するには、複数のオブジェクトではなく 1 つの Random オブジェクトを作成します。 .NET Core の Random クラスには、この制限はありません。

複数のインスタンス化を回避する

.NET Frameworkでは、2 つの乱数ジェネレーターを厳密なループまたは連続して初期化すると、同じ乱数シーケンスを生成できる 2 つの乱数ジェネレーターが作成されます。 乱数ジェネレーターのインスタンス化と初期化は比較的高価なプロセスであるため、ほとんどの場合、これは開発者の意図ではなく、パフォーマンスの問題につながる可能性があります。

パフォーマンスを向上させ、同一の数値シーケンスを生成する個別の乱数ジェネレーターを誤って作成しないようにするには、新しいRandomオブジェクトを作成して 1 つのRandom乱数を生成するのではなく、時間の経過と共に多数の乱数を生成するオブジェクトを 1 つ作成することをお勧めします。

ただし、 Random クラスはスレッド セーフではありません。 複数のスレッドからメソッドを呼び出す Random 場合は、次のセクションで説明するガイドラインに従ってください。

System.Random クラスとスレッド セーフ

個々 Random のオブジェクトをインスタンス化する代わりに、1 つの Random インスタンスを作成して、アプリに必要なすべての乱数を生成することをお勧めします。 ただし、 Random オブジェクトはスレッド セーフではありません。 アプリが複数のスレッドからメソッドを呼び出す Random 場合は、同期オブジェクトを使用して、一度に 1 つのスレッドのみが乱数ジェネレーターにアクセスできるようにする必要があります。 オブジェクトにスレッド セーフな方法で確実にアクセスできない Random 場合は、乱数を返すメソッドを呼び出すと 0 が返されます。

次の例では、C# lock ステートメント、F# ロック関数 、および Visual Basic SyncLock ステートメント を使用して、スレッド セーフな方法で 11 個のスレッドから 1 つの乱数ジェネレーターにアクセスできるようにします。 各スレッドは 200 万個の乱数を生成し、生成された乱数の数をカウントして合計を計算し、実行が完了したときにすべてのスレッドの合計を更新します。

using namespace System;
using namespace System::Threading;

ref class Example
{
private:
   [ThreadStatic] static double previous = 0.0;
   [ThreadStatic] static int perThreadCtr = 0;
   [ThreadStatic] static double perThreadTotal = 0.0;  
   static CancellationTokenSource^ source;
   static CountdownEvent^ countdown;
   static Object^ randLock;
   static Object^ numericLock;
   static Random^ rand;
   double totalValue = 0.0;
   int totalCount = 0;
   
public:
   Example()
   { 
      rand = gcnew Random();
      randLock = gcnew Object();
      numericLock = gcnew Object();
      countdown = gcnew CountdownEvent(1);
      source = gcnew CancellationTokenSource();
   } 

   void Execute()
   {   
      CancellationToken^ token = source->Token;

      for (int threads = 1; threads <= 10; threads++)
      {
         Thread^ newThread = gcnew Thread(gcnew ParameterizedThreadStart(this, &Example::GetRandomNumbers));
         newThread->Name = threads.ToString();
         newThread->Start(token);
      }
      this->GetRandomNumbers(token);
      
      countdown->Signal();
      // Make sure all threads have finished.
      countdown->Wait();

      Console::WriteLine("\nTotal random numbers generated: {0:N0}", totalCount);
      Console::WriteLine("Total sum of all random numbers: {0:N2}", totalValue);
      Console::WriteLine("Random number mean: {0:N4}", totalValue/totalCount);
   }

private:
   void GetRandomNumbers(Object^ o)
   {
      CancellationToken^ token = (CancellationToken) o;
      double result = 0.0;
      countdown->AddCount(1);
         
      try { 
         for (int ctr = 0; ctr < 2000000; ctr++)
         {
            // Make sure there's no corruption of Random.
            token->ThrowIfCancellationRequested();

            Monitor::Enter(randLock);
            result = rand->NextDouble();
            Monitor::Exit(randLock);
            // Check for corruption of Random instance.
            if ((result == previous) && result == 0) {
               source->Cancel();
            }
            else {
               previous = result;
            }
            perThreadCtr++;
            perThreadTotal += result;
         }      
       
         Console::WriteLine("Thread {0} finished execution.", 
                           Thread::CurrentThread->Name);
         Console::WriteLine("Random numbers generated: {0:N0}", perThreadCtr);
         Console::WriteLine("Sum of random numbers: {0:N2}", perThreadTotal);
         Console::WriteLine("Random number mean: {0:N4}\n", perThreadTotal/perThreadCtr);

         // Update overall totals.
         Monitor::Enter(numericLock);
         totalCount += perThreadCtr;
         totalValue += perThreadTotal;  
         Monitor::Exit(numericLock);
      }
      catch (OperationCanceledException^ e) {
         Console::WriteLine("Corruption in Thread {1}", e->GetType()->Name,
                            Thread::CurrentThread->Name);
      }
      finally {
         countdown->Signal();
      }
   }
};

void main()
{
   Example^ ex = gcnew Example();
   Thread::CurrentThread->Name = "Main";
   ex->Execute();
}
// The example displays output like the following:
//       Thread 6 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,491.05
//       Random number mean: 0.5002
//       
//       Thread 10 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,329.64
//       Random number mean: 0.4997
//       
//       Thread 4 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,166.89
//       Random number mean: 0.5001
//       
//       Thread 8 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,628.37
//       Random number mean: 0.4998
//       
//       Thread Main finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,920.89
//       Random number mean: 0.5000
//       
//       Thread 3 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,370.45
//       Random number mean: 0.4997
//       
//       Thread 7 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,330.92
//       Random number mean: 0.4997
//       
//       Thread 9 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,172.79
//       Random number mean: 0.5001
//       
//       Thread 5 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,079.43
//       Random number mean: 0.5000
//       
//       Thread 1 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,817.91
//       Random number mean: 0.4999
//       
//       Thread 2 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,930.63
//       Random number mean: 0.5000
//       
//       
//       Total random numbers generated: 22,000,000
//       Total sum of all random numbers: 10,998,238.98
//       Random number mean: 0.4999
using System;
using System.Threading;

public class Example
{
   [ThreadStatic] static double previous = 0.0;
   [ThreadStatic] static int perThreadCtr = 0;
   [ThreadStatic] static double perThreadTotal = 0.0;
   static CancellationTokenSource source;
   static CountdownEvent countdown;
   static Object randLock, numericLock;
   static Random rand;
   double totalValue = 0.0;
   int totalCount = 0;

   public Example()
   {
      rand = new Random();
      randLock = new Object();
      numericLock = new Object();
      countdown = new CountdownEvent(1);
      source = new CancellationTokenSource();
   }

   public static void Main()
   {
      Example ex = new Example();
      Thread.CurrentThread.Name = "Main";
      ex.Execute();
   }

   private void Execute()
   {
      CancellationToken token = source.Token;

      for (int threads = 1; threads <= 10; threads++)
      {
         Thread newThread = new Thread(this.GetRandomNumbers);
         newThread.Name = threads.ToString();
         newThread.Start(token);
      }
      this.GetRandomNumbers(token);

      countdown.Signal();
      // Make sure all threads have finished.
      countdown.Wait();
      source.Dispose();

      Console.WriteLine("\nTotal random numbers generated: {0:N0}", totalCount);
      Console.WriteLine("Total sum of all random numbers: {0:N2}", totalValue);
      Console.WriteLine("Random number mean: {0:N4}", totalValue/totalCount);
   }

   private void GetRandomNumbers(Object o)
   {
      CancellationToken token = (CancellationToken) o;
      double result = 0.0;
      countdown.AddCount(1);

      try {
         for (int ctr = 0; ctr < 2000000; ctr++)
         {
            // Make sure there's no corruption of Random.
            token.ThrowIfCancellationRequested();

            lock (randLock) {
               result = rand.NextDouble();
            }
            // Check for corruption of Random instance.
            if ((result == previous) && result == 0) {
               source.Cancel();
            }
            else {
               previous = result;
            }
            perThreadCtr++;
            perThreadTotal += result;
         }

         Console.WriteLine("Thread {0} finished execution.",
                           Thread.CurrentThread.Name);
         Console.WriteLine("Random numbers generated: {0:N0}", perThreadCtr);
         Console.WriteLine("Sum of random numbers: {0:N2}", perThreadTotal);
         Console.WriteLine("Random number mean: {0:N4}\n", perThreadTotal/perThreadCtr);

         // Update overall totals.
         lock (numericLock) {
            totalCount += perThreadCtr;
            totalValue += perThreadTotal;
         }
      }
      catch (OperationCanceledException e) {
         Console.WriteLine("Corruption in Thread {1}", e.GetType().Name, Thread.CurrentThread.Name);
      }
      finally {
         countdown.Signal();
      }
   }
}
// The example displays output like the following:
//       Thread 6 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,491.05
//       Random number mean: 0.5002
//
//       Thread 10 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,329.64
//       Random number mean: 0.4997
//
//       Thread 4 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,166.89
//       Random number mean: 0.5001
//
//       Thread 8 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,628.37
//       Random number mean: 0.4998
//
//       Thread Main finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,920.89
//       Random number mean: 0.5000
//
//       Thread 3 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,370.45
//       Random number mean: 0.4997
//
//       Thread 7 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,330.92
//       Random number mean: 0.4997
//
//       Thread 9 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,172.79
//       Random number mean: 0.5001
//
//       Thread 5 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,079.43
//       Random number mean: 0.5000
//
//       Thread 1 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,817.91
//       Random number mean: 0.4999
//
//       Thread 2 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,930.63
//       Random number mean: 0.5000
//
//
//       Total random numbers generated: 22,000,000
//       Total sum of all random numbers: 10,998,238.98
//       Random number mean: 0.4999
open System
open System.Threading

type Example() =
    [<ThreadStatic; DefaultValue>]
    static val mutable private previous : float
    
    [<ThreadStatic; DefaultValue>]
    static val mutable private perThreadCtr : int

    [<ThreadStatic; DefaultValue>]
    static val mutable private perThreadTotal : float

    static let source = new CancellationTokenSource()
    static let countdown = new CountdownEvent(1)
    static let randLock = obj ()
    static let numericLock = obj ()
    static let rand = Random()

    let mutable totalValue = 0.0
    let mutable totalCount = 0

    member _.GetRandomNumbers(token: CancellationToken) =
        let mutable result = 0.0
        countdown.AddCount 1
        try 
            try
                for _ = 0 to 1999999 do
                    // Make sure there's no corruption of Random.
                    token.ThrowIfCancellationRequested()

                    lock randLock (fun () -> 
                        result <- rand.NextDouble() )

                    // Check for corruption of Random instance.
                    if result = Example.previous && result = 0.0 then 
                        source.Cancel()
                    else
                        Example.previous <- result
                        
                    Example.perThreadCtr <- Example.perThreadCtr + 1
                    Example.perThreadTotal <- Example.perThreadTotal + result

                // Update overall totals.
                lock numericLock (fun () ->
                    // Show result.
                    printfn "Thread %s finished execution." Thread.CurrentThread.Name
                    printfn $"Random numbers generated: {Example.perThreadCtr:N0}" 
                    printfn $"Sum of random numbers: {Example.perThreadTotal:N2}" 
                    printfn $"Random number mean: {(Example.perThreadTotal / float Example.perThreadCtr):N4}\n"
                    
                    // Update overall totals.
                    totalCount <- totalCount + Example.perThreadCtr
                    totalValue <- totalValue + Example.perThreadTotal)

            with :? OperationCanceledException as e -> 
                printfn "Corruption in Thread %s %s" (e.GetType().Name) Thread.CurrentThread.Name
        finally
            countdown.Signal() |> ignore

    member this.Execute() =
        let token = source.Token
        for i = 1 to 10 do 
            let newThread = Thread(fun () -> this.GetRandomNumbers token)
            newThread.Name <- string i
            newThread.Start()
        this.GetRandomNumbers token
        
        countdown.Signal() |> ignore

        countdown.Wait()

        source.Dispose()

        printfn $"\nTotal random numbers generated: {totalCount:N0}"
        printfn $"Total sum of all random numbers: {totalValue:N2}"
        printfn $"Random number mean: {(totalValue / float totalCount):N4}"

let ex = Example()
Thread.CurrentThread.Name <- "Main"
ex.Execute()

// The example displays output like the following:
//       Thread 6 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,491.05
//       Random number mean: 0.5002
//
//       Thread 10 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,329.64
//       Random number mean: 0.4997
//
//       Thread 4 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,166.89
//       Random number mean: 0.5001
//
//       Thread 8 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,628.37
//       Random number mean: 0.4998
//
//       Thread Main finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,920.89
//       Random number mean: 0.5000
//
//       Thread 3 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,370.45
//       Random number mean: 0.4997
//
//       Thread 7 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,330.92
//       Random number mean: 0.4997
//
//       Thread 9 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,172.79
//       Random number mean: 0.5001
//
//       Thread 5 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,079.43
//       Random number mean: 0.5000
//
//       Thread 1 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,817.91
//       Random number mean: 0.4999
//
//       Thread 2 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,930.63
//       Random number mean: 0.5000
//
//
//       Total random numbers generated: 22,000,000
//       Total sum of all random numbers: 10,998,238.98
//       Random number mean: 0.4999
Imports System.Threading

Module Example
   <ThreadStatic> Dim previous As Double = 0.0
   <ThreadStatic> Dim perThreadCtr As Integer = 0
   <ThreadStatic> Dim perThreadTotal As Double = 0.0  
   Dim source As New CancellationTokenSource()
   Dim countdown As New CountdownEvent(1) 
   Dim randLock As New Object()
   Dim numericLock As New Object()
   Dim rand As New Random()
   Dim totalValue As Double = 0.0
   Dim totalCount As Integer = 0
   
   Public Sub Main()
      Thread.CurrentThread.Name = "Main"

      Dim token As CancellationToken = source.Token 
      For threads As Integer = 1 To 10
         Dim newThread As New Thread(AddressOf GetRandomNumbers)
         newThread.Name = threads.ToString()
         newThread.Start(token)
      Next
      GetRandomNumbers(token)
      
      countdown.Signal()
      ' Make sure all threads have finished.
      countdown.Wait()

      Console.WriteLine()
      Console.WriteLine("Total random numbers generated: {0:N0}", totalCount)
      Console.WriteLine("Total sum of all random numbers: {0:N2}", totalValue)
      Console.WriteLine("Random number mean: {0:N4}", totalValue/totalCount)
   End Sub

   Private Sub GetRandomNumbers(o As Object)
      Dim token As CancellationToken = CType(o, CancellationToken)
      Dim result As Double = 0.0
      countdown.AddCount(1)
         
      Try  
         For ctr As Integer = 1 To 2000000
            ' Make sure there's no corruption of Random.
            token.ThrowIfCancellationRequested()

            SyncLock randLock
               result = rand.NextDouble()
            End SyncLock
            ' Check for corruption of Random instance.
            If result = previous AndAlso result = 0 Then 
               source.Cancel()
            Else 
               previous = result
            End If
            perThreadCtr += 1
            perThreadTotal += result
         Next      
       
         Console.WriteLine("Thread {0} finished execution.", 
                           Thread.CurrentThread.Name)
         Console.WriteLine("Random numbers generated: {0:N0}", perThreadCtr)
         Console.WriteLine("Sum of random numbers: {0:N2}", perThreadTotal)
         Console.WriteLine("Random number mean: {0:N4}", perThreadTotal/perThreadCtr)
         Console.WriteLine()
         
         ' Update overall totals.
         SyncLock numericLock
            totalCount += perThreadCtr
            totalValue += perThreadTotal  
         End SyncLock
      Catch e As OperationCanceledException
         Console.WriteLine("Corruption in Thread {1}", e.GetType().Name, Thread.CurrentThread.Name)
      Finally 
         countdown.Signal()
         source.Dispose()
      End Try
   End Sub
End Module
' The example displays output like the following:
'       Thread 6 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,491.05
'       Random number mean: 0.5002
'       
'       Thread 10 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,329.64
'       Random number mean: 0.4997
'       
'       Thread 4 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,166.89
'       Random number mean: 0.5001
'       
'       Thread 8 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,628.37
'       Random number mean: 0.4998
'       
'       Thread Main finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,920.89
'       Random number mean: 0.5000
'       
'       Thread 3 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,370.45
'       Random number mean: 0.4997
'       
'       Thread 7 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,330.92
'       Random number mean: 0.4997
'       
'       Thread 9 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,172.79
'       Random number mean: 0.5001
'       
'       Thread 5 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,079.43
'       Random number mean: 0.5000
'       
'       Thread 1 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,817.91
'       Random number mean: 0.4999
'       
'       Thread 2 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,930.63
'       Random number mean: 0.5000
'       
'       
'       Total random numbers generated: 22,000,000
'       Total sum of all random numbers: 10,998,238.98
'       Random number mean: 0.4999

この例では、次の方法でスレッド セーフを確保します。

  • 属性は ThreadStaticAttribute 、生成された乱数の合計数と各スレッドの合計を追跡するスレッドローカル変数を定義するために使用されます。

  • ロック (C# のlockステートメント、F# の関数、Visual SyncLock Basic の ステートメント) は、lockすべてのスレッドで生成されたすべての乱数の合計数と合計の変数へのアクセスを保護します。

  • セマフォ (CountdownEventオブジェクト) は、他のすべてのスレッドが実行を完了するまで、メインスレッドがブロックされるようにするために使用されます。

  • この例では、乱数生成メソッドに対する 2 つの連続する呼び出しが 0 を返すかどうかを判断することで、乱数ジェネレーターが破損したかどうかを確認します。 破損が検出された場合、この例では オブジェクトを CancellationTokenSource 使用して、すべてのスレッドを取り消す必要があることを通知します。

  • 各乱数を生成する前に、各スレッドは オブジェクトの状態を CancellationToken 確認します。 取り消しが要求された場合、この例では メソッドを CancellationToken.ThrowIfCancellationRequested 呼び出してスレッドを取り消します。

次の例は、オブジェクトではなく オブジェクトとラムダ式を Task 使用する点を除き、最初の Thread 例と同じです。

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   static Object randLock, numericLock;
   static Random rand;
   static CancellationTokenSource source;
   double totalValue = 0.0;
   int totalCount = 0;

   public Example()
   {
      rand = new Random();
      randLock = new Object();
      numericLock = new Object();
      source = new CancellationTokenSource();
   }

   public static async Task Main()
   {
      Example ex = new Example();
      Thread.CurrentThread.Name = "Main";
      await ex.Execute();
   }

   private Task Execute()
   {
      List<Task> tasks = new List<Task>();

      for (int ctr = 0; ctr <= 10; ctr++)
      {
         CancellationToken token = source.Token;
         int taskNo = ctr;
         tasks.Add(Task.Run( () =>
            {
               double previous = 0.0;
               int taskCtr = 0;
               double taskTotal = 0.0;
               double result = 0.0;

               for (int n = 0; n < 2000000; n++)
               {
                  // Make sure there's no corruption of Random.
                  token.ThrowIfCancellationRequested();

                  lock (randLock) {
                     result = rand.NextDouble();
                  }
                  // Check for corruption of Random instance.
                  if ((result == previous) && result == 0) {
                     source.Cancel();
                  }
                  else {
                     previous = result;
                  }
                  taskCtr++;
                  taskTotal += result;
               }

               // Show result.
               Console.WriteLine("Task {0} finished execution.", taskNo);
               Console.WriteLine("Random numbers generated: {0:N0}", taskCtr);
               Console.WriteLine("Sum of random numbers: {0:N2}", taskTotal);
               Console.WriteLine("Random number mean: {0:N4}\n", taskTotal/taskCtr);

               // Update overall totals.
               lock (numericLock) {
                  totalCount += taskCtr;
                  totalValue += taskTotal;
               }
            },
         token));
      }
      try {
         await Task.WhenAll(tasks.ToArray());
         Console.WriteLine("\nTotal random numbers generated: {0:N0}", totalCount);
         Console.WriteLine("Total sum of all random numbers: {0:N2}", totalValue);
         Console.WriteLine("Random number mean: {0:N4}", totalValue/totalCount);
      }
      catch (AggregateException e) {
         foreach (Exception inner in e.InnerExceptions) {
            TaskCanceledException canc = inner as TaskCanceledException;
            if (canc != null)
               Console.WriteLine("Task #{0} cancelled.", canc.Task.Id);
            else
               Console.WriteLine("Exception: {0}", inner.GetType().Name);
         }
      }
      finally {
         source.Dispose();
      }
   }
}
// The example displays output like the following:
//       Task 1 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,502.47
//       Random number mean: 0.5003
//
//       Task 0 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,445.63
//       Random number mean: 0.5002
//
//       Task 2 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,556.04
//       Random number mean: 0.5003
//
//       Task 3 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,178.87
//       Random number mean: 0.5001
//
//       Task 4 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,819.17
//       Random number mean: 0.4999
//
//       Task 5 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,190.58
//       Random number mean: 0.5001
//
//       Task 6 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,720.21
//       Random number mean: 0.4999
//
//       Task 7 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,000.96
//       Random number mean: 0.4995
//
//       Task 8 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,499.33
//       Random number mean: 0.4997
//
//       Task 9 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,193.25
//       Random number mean: 0.5001
//
//       Task 10 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,960.82
//       Random number mean: 0.5000
//
//
//       Total random numbers generated: 22,000,000
//       Total sum of all random numbers: 11,000,067.33
//       Random number mean: 0.5000
open System
open System.Threading
open System.Threading.Tasks

type Example() =
    static let source = new CancellationTokenSource()
    static let rand = Random()

    static let randLock = obj ()
    static let numericLock = obj ()

    let mutable totalValue = 0.0
    let mutable totalCount = 0

    member _.Execute() =
        use source = source // Dispose of the CancellationTokenSource when we're done with it.
        let token = source.Token

        let tasks =
            [| for i = 0 to 10 do
                   Task.Run(
                       (fun () ->
                           let mutable previous = 0.0
                           let mutable taskCtr = 0
                           let mutable taskTotal = 0.0
                           let mutable result = 0.0

                           for _ = 1 to 2000000 do
                               // Make sure there's no corruption of Random.
                               token.ThrowIfCancellationRequested()

                               lock randLock (fun () -> result <- rand.NextDouble())

                               // Check for corruption of Random instance.
                               if result = previous && result = 0.0 then
                                   source.Cancel()
                               else
                                   previous <- result

                               taskCtr <- taskCtr + 1
                               taskTotal <- taskTotal + result

                           lock numericLock (fun () ->
                               // Show result.
                               printfn "Task %i finished execution." i
                               printfn $"Random numbers generated: {taskCtr:N0}"
                               printfn $"Sum of random numbers: {taskTotal:N2}"
                               printfn $"Random number mean: {(taskTotal / float taskCtr):N4}\n"

                               // Update overall totals.
                               totalCount <- totalCount + taskCtr
                               totalValue <- totalValue + taskTotal)),
                       token
                   ) |]

        try
            // Run tasks with F# Async.
            Task.WhenAll tasks
            |> Async.AwaitTask
            |> Async.RunSynchronously

            printfn $"\nTotal random numbers generated: {totalCount:N0}"
            printfn $"Total sum of all random numbers: {totalValue:N2}"
            printfn $"Random number mean: {(totalValue / float totalCount):N4}"
        with
        | :? AggregateException as e ->
            for inner in e.InnerExceptions do
                match inner with
                | :? TaskCanceledException as canc ->
                    if canc <> null then
                        printfn $"Task #{canc.Task.Id} cancelled"
                    else
                        printfn $"Exception: {inner.GetType().Name}"
                | _ -> ()

let ex = Example()
Thread.CurrentThread.Name <- "Main"
ex.Execute()

// The example displays output like the following:
//       Task 1 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,502.47
//       Random number mean: 0.5003
//
//       Task 0 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,445.63
//       Random number mean: 0.5002
//
//       Task 2 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,556.04
//       Random number mean: 0.5003
//
//       Task 3 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,178.87
//       Random number mean: 0.5001
//
//       Task 4 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,819.17
//       Random number mean: 0.4999
//
//       Task 5 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,190.58
//       Random number mean: 0.5001
//
//       Task 6 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,720.21
//       Random number mean: 0.4999
//
//       Task 7 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,000.96
//       Random number mean: 0.4995
//
//       Task 8 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,499.33
//       Random number mean: 0.4997
//
//       Task 9 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,193.25
//       Random number mean: 0.5001
//
//       Task 10 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,960.82
//       Random number mean: 0.5000
//
//
//       Total random numbers generated: 22,000,000
//       Total sum of all random numbers: 11,000,067.33
//       Random number mean: 0.5000
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Dim source As New CancellationTokenSource()
   Dim randLock As New Object()
   Dim numericLock As New Object()
   Dim rand As New Random()
   Dim totalValue As Double = 0.0
   Dim totalCount As Integer = 0
   
   Public Sub Main()
      Dim tasks As New List(Of Task)()
      
      For ctr As Integer = 1 To 10
         Dim token As CancellationToken = source.Token 
         Dim taskNo As Integer = ctr
         tasks.Add(Task.Run( 
                   Sub()
                      Dim previous As Double = 0.0
                      Dim taskCtr As Integer = 0
                      Dim taskTotal As Double = 0.0
                      Dim result As Double = 0.0

                      For n As Integer = 1 To 2000000
                         ' Make sure there's no corruption of Random.
                         token.ThrowIfCancellationRequested()
      
                         SyncLock randLock
                           result = rand.NextDouble()
                         End SyncLock
                         ' Check for corruption of Random instance.
                         If result = previous AndAlso result = 0 Then
                           source.Cancel()
                         Else 
                           previous = result
                         End If
                        taskCtr += 1
                        taskTotal += result
                      Next   

                      ' Show result.
                     Console.WriteLine("Task {0} finished execution.", taskNo)
                     Console.WriteLine("Random numbers generated: {0:N0}", taskCtr)
                     Console.WriteLine("Sum of random numbers: {0:N2}", taskTotal)
                     Console.WriteLine("Random number mean: {0:N4}", taskTotal/taskCtr)
                     Console.WriteLine()
                     
                     ' Update overall totals.
                     SyncLock numericLock
                        totalCount += taskCtr
                        totalValue += taskTotal  
                     End SyncLock
                   End Sub, token))
      Next

      Try
         Task.WaitAll(tasks.ToArray())
         Console.WriteLine()
         Console.WriteLine("Total random numbers generated: {0:N0}", totalCount)
         Console.WriteLine("Total sum of all random numbers: {0:N2}", totalValue)
         Console.WriteLine("Random number mean: {0:N4}", totalValue/totalCount)
      Catch e As AggregateException
         For Each inner As Exception In e.InnerExceptions
            Dim canc As TaskCanceledException = TryCast(inner, TaskCanceledException)
            If canc IsNot Nothing Then
               Console.WriteLine("Task #{0} cancelled.", canc.Task.Id)
            Else
               Console.WriteLine("Exception: {0}", inner.GetType().Name)
            End If   
         Next         
      Finally
         source.Dispose()
      End Try
   End Sub
End Module
' The example displays output like the following:
'       Task 1 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,502.47
'       Random number mean: 0.5003
'       
'       Task 0 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,445.63
'       Random number mean: 0.5002
'       
'       Task 2 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,556.04
'       Random number mean: 0.5003
'       
'       Task 3 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,178.87
'       Random number mean: 0.5001
'       
'       Task 4 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,819.17
'       Random number mean: 0.4999
'       
'       Task 5 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,190.58
'       Random number mean: 0.5001
'       
'       Task 6 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,720.21
'       Random number mean: 0.4999
'       
'       Task 7 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,000.96
'       Random number mean: 0.4995
'       
'       Task 8 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,499.33
'       Random number mean: 0.4997
'       
'       Task 9 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 1,000,193.25
'       Random number mean: 0.5001
'       
'       Task 10 finished execution.
'       Random numbers generated: 2,000,000
'       Sum of random numbers: 999,960.82
'       Random number mean: 0.5000
'       
'       
'       Total random numbers generated: 22,000,000
'       Total sum of all random numbers: 11,000,067.33
'       Random number mean: 0.5000

これは、次の点で最初の例とは異なります。

  • 生成された乱数の数とその各タスクの合計を追跡する変数は、タスクに対してローカルであるため、 属性を ThreadStaticAttribute 使用する必要はありません。

  • 静的Task.WaitAllメソッドは、すべてのタスクが完了する前にメイン スレッドが完了しないようにするために使用されます。 オブジェクトは必要 CountdownEvent ありません。

  • タスクの取り消しによって発生する例外は、 メソッドに Task.WaitAll 表示されます。 前の例では、各スレッドによって処理されます。

さまざまな種類の乱数の生成

乱数ジェネレーターには、次の種類の乱数を生成できるメソッドが用意されています。

  • 一連の Byte 値。 バイト値の数を決定するには、メソッドがメソッドに返す要素の数に初期化された配列を NextBytes 渡します。 次の例では、20 バイトが生成されます。

    using namespace System;
    
    void main()
    {
       Random^ rnd = gcnew Random();
       array<Byte>^ bytes = gcnew array<Byte>(20);
       rnd->NextBytes(bytes);
       for (int ctr = 1; ctr <= bytes->Length; ctr++) {
          Console::Write("{0,3}   ", bytes[ctr - 1]);
          if (ctr % 10 == 0) Console::WriteLine();
       } 
    }
    // The example displays output like the following:
    //       141    48   189    66   134   212   211    71   161    56
    //       181   166   220   133     9   252   222    57    62    62
    
    Random rnd = new Random();
    Byte[] bytes = new Byte[20];
    rnd.NextBytes(bytes);
    for (int ctr = 1; ctr <= bytes.Length; ctr++) {
       Console.Write("{0,3}   ", bytes[ctr - 1]);
       if (ctr % 10 == 0) Console.WriteLine();
    }
    
    // The example displays output like the following:
    //       141    48   189    66   134   212   211    71   161    56
    //       181   166   220   133     9   252   222    57    62    62
    
    let rnd = Random()
    let bytes = Array.zeroCreate 20
    rnd.NextBytes bytes
    
    for i = 1 to bytes.Length do
        printf "%3i   " bytes.[i - 1]
        if (i % 10 = 0) then printfn ""
    
    // The example displays output like the following:
    //       141    48   189    66   134   212   211    71   161    56
    //       181   166   220   133     9   252   222    57    62    62
    
    Module Example
       Public Sub Main()
          Dim rnd As New Random()
          Dim bytes(19) As Byte
          rnd.NextBytes(bytes)  
          For ctr As Integer = 1 To bytes.Length
             Console.Write("{0,3}   ", bytes(ctr - 1))
             If ctr Mod 10 = 0 Then Console.WriteLine()
          Next 
       End Sub
    End Module
    ' The example displays output like the following:
    '       141    48   189    66   134   212   211    71   161    56
    '       181   166   220   133     9   252   222    57    62    62
    
  • 1 つの整数。 メソッドを呼び出して 0 から最大値 (Int32.MaxValue - 1) までの整数、メソッドを呼び出Next()して 0 から特定の値までの整数、または メソッドを呼び出Next(Int32)Next(Int32, Int32)して値の範囲内の整数を選択できます。 パラメーター化されたオーバーロードでは、指定された最大値は排他的です。つまり、生成される実際の最大数は、指定された値より 1 小さくなります。

    次の例では、 メソッドを Next(Int32, Int32) 呼び出して、-10 から 10 までの 10 個の乱数を生成します。 メソッドの 2 番目の引数は、 メソッドによって返されるランダムな値の範囲の排他的上限を指定します。 つまり、メソッドが返すことができる最大の整数は、この値より 1 小さい値です。

    using namespace System;
    
    void main()
    {
       Random^ rnd = gcnew Random();
       for (int ctr = 0; ctr < 10; ctr++) {
          Console::Write("{0,3}   ", rnd->Next(-10, 11));
       }
    }
    // The example displays output like the following:
    //    2     9    -3     2     4    -7    -3    -8    -8     5
    
    Random rnd = new Random();
    for (int ctr = 0; ctr < 10; ctr++) {
       Console.Write("{0,3}   ", rnd.Next(-10, 11));
    }
    
    // The example displays output like the following:
    //    2     9    -3     2     4    -7    -3    -8    -8     5
    
    let rnd = Random()
    for i = 0 to 9 do 
        printf "%3i   " (rnd.Next(-10, 11))
    
    // The example displays output like the following:
    //    2     9    -3     2     4    -7    -3    -8    -8     5
    
    Module Example
       Public Sub Main()
          Dim rnd As New Random()
          For ctr As Integer = 0 To 9
             Console.Write("{0,3}   ", rnd.Next(-10, 11))
          Next
       End Sub
    End Module
    ' The example displays output like the following:
    '    2     9    -3     2     4    -7    -3    -8    -8     5
    
  • メソッドを呼び出 NextDouble して、0.0 から 1.0 未満の 1 つの浮動小数点値。 メソッドによって返される乱数の排他的上限は 1 であるため、実際の上限は 0.9999999999999978 です。 次の例では、10 個のランダムな浮動小数点数を生成します。

    using namespace System;
    
    void main()
    {
       Random^ rnd = gcnew Random();
       for (int ctr = 0; ctr < 10; ctr++) {
          Console::Write("{0,-19:R}   ", rnd->NextDouble());
          if ((ctr + 1) % 3 == 0) Console::WriteLine();
       }
    }
    // The example displays output like the following:
    //    0.7911680553998649    0.0903414949264105    0.79776258291572455    
    //    0.615568345233597     0.652644504165577     0.84023809378977776   
    //    0.099662564741290441   0.91341467383942321  0.96018602045261581   
    //    0.74772306473354022
    
    Random rnd = new Random();
    for (int ctr = 0; ctr < 10; ctr++) {
       Console.Write("{0,-19:R}   ", rnd.NextDouble());
       if ((ctr + 1) % 3 == 0) Console.WriteLine();
    }
    
    // The example displays output like the following:
    //    0.7911680553998649    0.0903414949264105    0.79776258291572455
    //    0.615568345233597     0.652644504165577     0.84023809378977776
    //    0.099662564741290441   0.91341467383942321  0.96018602045261581
    //    0.74772306473354022
    
    let rnd = Random()
    for i = 0 to 9 do 
        printf $"{rnd.NextDouble(),-19:R}   "
        if (i + 1) % 3 = 0 then printfn ""
    
    // The example displays output like the following:
    //    0.7911680553998649    0.0903414949264105    0.79776258291572455
    //    0.615568345233597     0.652644504165577     0.84023809378977776
    //    0.099662564741290441   0.91341467383942321  0.96018602045261581
    //    0.74772306473354022
    
    Module Example
       Public Sub Main()
          Dim rnd As New Random()
          For ctr As Integer = 0 To 9
             Console.Write("{0,-19:R}   ", rnd.NextDouble())
             If (ctr + 1) Mod 3 = 0 Then Console.WriteLine()
          Next
       End Sub
    End Module
    ' The example displays output like the following:
    '    0.7911680553998649    0.0903414949264105    0.79776258291572455    
    '    0.615568345233597     0.652644504165577     0.84023809378977776   
    '    0.099662564741290441  0.91341467383942321   0.96018602045261581   
    '    0.74772306473354022
    

重要

Next(Int32, Int32)メソッドを使用すると、返される乱数の範囲を指定できます。 ただし、返される数値の maxValue 上限範囲を指定する パラメーターは、包括的な値ではなく、排他的です。 つまり、メソッド呼び出し Next(0, 100) は 0 から 100 の間ではなく、0 ~ 99 の値を返します。

また、 クラスは Randomランダムな T:System.Boolean 値の生成、 0 から 1 以外の範囲のランダムな浮動小数点値の生成、 ランダムな 64 ビット整数の生成、 配列またはコレクションからの一意の要素のランダムな取得などのタスクにも使用できます。 これらのタスクとその他の一般的なタスクについては、「 System.Random to... の使用方法 」セクションを参照してください。

独自のアルゴリズムの置き換え

クラスから Random 継承し、乱数生成アルゴリズムを指定することで、独自の乱数ジェネレーターを実装できます。 独自のアルゴリズムを指定するには、乱数生成アルゴリズムを Sample 実装する メソッドをオーバーライドする必要があります。 また、オーバーライドされたメソッドを Next()確実に呼び出すために、、 Next(Int32, Int32)、および NextBytes の各メソッドをオーバーライド Sample する必要があります。 メソッドと NextDouble メソッドをオーバーライドNext(Int32)する必要はありません。

クラスから派生し、その既定の Random 擬似乱数ジェネレーターを変更する例については、リファレンス ページを Sample 参照してください。

System.Random を使用する方法...

次のセクションでは、アプリで乱数を使用する方法の一部について説明し、サンプル コードを提供します。

ランダムな値の同じシーケンスを取得する

ソフトウェア テスト シナリオやゲーム プレイで同じ乱数シーケンスを生成したい場合があります。 同じ乱数シーケンスを使用してテストすると、回帰を検出し、バグ修正を確認できます。 ゲームで乱数の同じシーケンスを使用すると、以前のゲームを再生することができます。

コンストラクターに同じシード値を指定することで、同じ乱数シーケンスを Random(Int32) 生成できます。 シード値は、擬似乱数生成アルゴリズムの開始値を提供します。 次の例では、100100 を任意のシード値として使用してオブジェクトを Random インスタンス化し、20 個のランダムな浮動小数点値を表示し、シード値を保持します。 次に、シード値を復元し、新しい乱数ジェネレーターをインスタンス化し、同じ 20 個のランダム浮動小数点値を表示します。 この例では、.NET Frameworkの異なるバージョンで実行すると、乱数のシーケンスが異なる場合があることに注意してください。

using System;
using System.IO;

public class Example
{
   public static void Main()
   {
      int seed = 100100;
      ShowRandomNumbers(seed);
      Console.WriteLine();

      PersistSeed(seed);

      DisplayNewRandomNumbers();
   }

   private static void ShowRandomNumbers(int seed)
   {
      Random rnd = new Random(seed);
      for (int ctr = 0; ctr <= 20; ctr++)
         Console.WriteLine(rnd.NextDouble());
   }

   private static void PersistSeed(int seed)
   {
      FileStream fs = new FileStream(@".\seed.dat", FileMode.Create);
      BinaryWriter bin = new BinaryWriter(fs);
      bin.Write(seed);
      bin.Close();
   }

   private static void DisplayNewRandomNumbers()
   {
      FileStream fs = new FileStream(@".\seed.dat", FileMode.Open);
      BinaryReader bin = new BinaryReader(fs);
      int seed = bin.ReadInt32();
      bin.Close();

      Random rnd = new Random(seed);
      for (int ctr = 0; ctr <= 20; ctr++)
         Console.WriteLine(rnd.NextDouble());
   }
}
// The example displays output like the following:
//       0.500193602172748
//       0.0209461245783354
//       0.465869495396442
//       0.195512794514891
//       0.928583675496552
//       0.729333720509584
//       0.381455668891527
//       0.0508996467343064
//       0.019261200921266
//       0.258578445417145
//       0.0177532266908107
//       0.983277184415272
//       0.483650274334313
//       0.0219647376900375
//       0.165910115077118
//       0.572085966622497
//       0.805291457942357
//       0.927985211335116
//       0.4228545699375
//       0.523320379910674
//       0.157783938645285
//
//       0.500193602172748
//       0.0209461245783354
//       0.465869495396442
//       0.195512794514891
//       0.928583675496552
//       0.729333720509584
//       0.381455668891527
//       0.0508996467343064
//       0.019261200921266
//       0.258578445417145
//       0.0177532266908107
//       0.983277184415272
//       0.483650274334313
//       0.0219647376900375
//       0.165910115077118
//       0.572085966622497
//       0.805291457942357
//       0.927985211335116
//       0.4228545699375
//       0.523320379910674
//       0.157783938645285
open System
open System.IO

let showRandomNumbers seed =
    let rnd = Random seed
    for _ = 0 to 20 do 
        printfn $"{rnd.NextDouble()}"

let persistSeed (seed: int) =
    use bin = new BinaryWriter(new FileStream(@".\seed.dat", FileMode.Create))
    bin.Write seed

let displayNewRandomNumbers () =
    use bin = new BinaryReader(new FileStream(@".\seed.dat", FileMode.Open))
    let seed = bin.ReadInt32()

    let rnd = Random seed
    for _ = 0 to 20 do 
        printfn $"{rnd.NextDouble()}"

let seed = 100100
showRandomNumbers seed
printfn ""

persistSeed seed

displayNewRandomNumbers ()

// The example displays output like the following:
//       0.500193602172748
//       0.0209461245783354
//       0.465869495396442
//       0.195512794514891
//       0.928583675496552
//       0.729333720509584
//       0.381455668891527
//       0.0508996467343064
//       0.019261200921266
//       0.258578445417145
//       0.0177532266908107
//       0.983277184415272
//       0.483650274334313
//       0.0219647376900375
//       0.165910115077118
//       0.572085966622497
//       0.805291457942357
//       0.927985211335116
//       0.4228545699375
//       0.523320379910674
//       0.157783938645285
//
//       0.500193602172748
//       0.0209461245783354
//       0.465869495396442
//       0.195512794514891
//       0.928583675496552
//       0.729333720509584
//       0.381455668891527
//       0.0508996467343064
//       0.019261200921266
//       0.258578445417145
//       0.0177532266908107
//       0.983277184415272
//       0.483650274334313
//       0.0219647376900375
//       0.165910115077118
//       0.572085966622497
//       0.805291457942357
//       0.927985211335116
//       0.4228545699375
//       0.523320379910674
//       0.157783938645285
using namespace System;
using namespace System::IO;

ref class RandomMethods
{
internal:
   static void ShowRandomNumbers(int seed)
   {
      Random^ rnd = gcnew Random(seed);
      for (int ctr = 0; ctr <= 20; ctr++)
         Console::WriteLine(rnd->NextDouble());
   }
   
   static void PersistSeed(int seed)
   {
      FileStream^ fs = gcnew FileStream(".\\seed.dat", FileMode::Create);
      BinaryWriter^ bin = gcnew BinaryWriter(fs);
      bin->Write(seed);
      bin->Close();
   }
   
   static void DisplayNewRandomNumbers()
   {
      FileStream^ fs = gcnew FileStream(".\\seed.dat", FileMode::Open);
      BinaryReader^ bin = gcnew BinaryReader(fs);
      int seed = bin->ReadInt32();
      bin->Close();
      
      Random^ rnd = gcnew Random(seed);
      for (int ctr = 0; ctr <= 20; ctr++)
         Console::WriteLine(rnd->NextDouble());
   }
};

void main()
{
   int seed = 100100;
   RandomMethods::ShowRandomNumbers(seed);
   Console::WriteLine();

   RandomMethods::PersistSeed(seed);

   RandomMethods::DisplayNewRandomNumbers();
}
// The example displays output like the following:
//       0.500193602172748
//       0.0209461245783354
//       0.465869495396442
//       0.195512794514891
//       0.928583675496552
//       0.729333720509584
//       0.381455668891527
//       0.0508996467343064
//       0.019261200921266
//       0.258578445417145
//       0.0177532266908107
//       0.983277184415272
//       0.483650274334313
//       0.0219647376900375
//       0.165910115077118
//       0.572085966622497
//       0.805291457942357
//       0.927985211335116
//       0.4228545699375
//       0.523320379910674
//       0.157783938645285
//       
//       0.500193602172748
//       0.0209461245783354
//       0.465869495396442
//       0.195512794514891
//       0.928583675496552
//       0.729333720509584
//       0.381455668891527
//       0.0508996467343064
//       0.019261200921266
//       0.258578445417145
//       0.0177532266908107
//       0.983277184415272
//       0.483650274334313
//       0.0219647376900375
//       0.165910115077118
//       0.572085966622497
//       0.805291457942357
//       0.927985211335116
//       0.4228545699375
//       0.523320379910674
//       0.157783938645285
Imports System.IO

Module Example
   Public Sub Main()
      Dim seed As Integer = 100100
      ShowRandomNumbers(seed)
      Console.WriteLine()
      
      PersistSeed(seed)
      
      DisplayNewRandomNumbers() 
   End Sub
   
   Private Sub ShowRandomNumbers(seed As Integer)
      Dim rnd As New Random(seed)
      For ctr As Integer = 0 To 20
         Console.WriteLine(rnd.NextDouble())
      Next
   End Sub
   
   Private Sub PersistSeed(seed As Integer)
      Dim fs As New FileStream(".\seed.dat", FileMode.Create)
      Dim bin As New BinaryWriter(fs)
      bin.Write(seed)
      bin.Close()
   End Sub
   
   Private Sub DisplayNewRandomNumbers()
      Dim fs As New FileStream(".\seed.dat", FileMode.Open)
      Dim bin As New BinaryReader(fs)
      Dim seed As Integer = bin.ReadInt32()
      bin.Close()
      
      Dim rnd As New Random(seed)
      For ctr As Integer = 0 To 20
         Console.WriteLine(rnd.NextDouble())
      Next
   End Sub
End Module
' The example displays output like the following:
'       0.500193602172748
'       0.0209461245783354
'       0.465869495396442
'       0.195512794514891
'       0.928583675496552
'       0.729333720509584
'       0.381455668891527
'       0.0508996467343064
'       0.019261200921266
'       0.258578445417145
'       0.0177532266908107
'       0.983277184415272
'       0.483650274334313
'       0.0219647376900375
'       0.165910115077118
'       0.572085966622497
'       0.805291457942357
'       0.927985211335116
'       0.4228545699375
'       0.523320379910674
'       0.157783938645285
'       
'       0.500193602172748
'       0.0209461245783354
'       0.465869495396442
'       0.195512794514891
'       0.928583675496552
'       0.729333720509584
'       0.381455668891527
'       0.0508996467343064
'       0.019261200921266
'       0.258578445417145
'       0.0177532266908107
'       0.983277184415272
'       0.483650274334313
'       0.0219647376900375
'       0.165910115077118
'       0.572085966622497
'       0.805291457942357
'       0.927985211335116
'       0.4228545699375
'       0.523320379910674
'       0.157783938645285

乱数の一意のシーケンスを取得する

クラスのインスタンスに異なるシード値を Random 指定すると、各乱数ジェネレーターによって異なる値シーケンスが生成されます。 シード値は、コンストラクターを呼び出すことによって明示的に指定することも、コンストラクターを Random(Int32) 呼び出すことによって暗黙的に指定 Random() することもできます。 ほとんどの開発者は、システム クロックを使用するパラメーターなしのコンストラクターを呼び出します。 次の例では、この方法を使用して 2 つの Random インスタンスをインスタンス化します。 各インスタンスには、一連の 10 個のランダムな整数が表示されます。

using namespace System;
using namespace System::Threading;

void main()
{
   Console::WriteLine("Instantiating two random number generators...");
   Random^ rnd1 = gcnew Random();
   Thread::Sleep(2000);
   Random^ rnd2 = gcnew Random();
   
   Console::WriteLine("\nThe first random number generator:");
   for (int ctr = 1; ctr <= 10; ctr++)
      Console::WriteLine("   {0}", rnd1->Next());

   Console::WriteLine("\nThe second random number generator:");
   for (int ctr = 1; ctr <= 10; ctr++)
      Console::WriteLine("   {0}", rnd2->Next());
}
// The example displays output like the following:
//       Instantiating two random number generators...
//       
//       The first random number generator:
//          643164361
//          1606571630
//          1725607587
//          2138048432
//          496874898
//          1969147632
//          2034533749
//          1840964542
//          412380298
//          47518930
//       
//       The second random number generator:
//          1251659083
//          1514185439
//          1465798544
//          517841554
//          1821920222
//          195154223
//          1538948391
//          1548375095
//          546062716
//          897797880
using System;
using System.Threading;

public class Example
{
   public static void Main()
   {
      Console.WriteLine("Instantiating two random number generators...");
      Random rnd1 = new Random();
      Thread.Sleep(2000);
      Random rnd2 = new Random();

      Console.WriteLine("\nThe first random number generator:");
      for (int ctr = 1; ctr <= 10; ctr++)
         Console.WriteLine("   {0}", rnd1.Next());

      Console.WriteLine("\nThe second random number generator:");
      for (int ctr = 1; ctr <= 10; ctr++)
         Console.WriteLine("   {0}", rnd2.Next());
   }
}
// The example displays output like the following:
//       Instantiating two random number generators...
//
//       The first random number generator:
//          643164361
//          1606571630
//          1725607587
//          2138048432
//          496874898
//          1969147632
//          2034533749
//          1840964542
//          412380298
//          47518930
//
//       The second random number generator:
//          1251659083
//          1514185439
//          1465798544
//          517841554
//          1821920222
//          195154223
//          1538948391
//          1548375095
//          546062716
//          897797880
open System
open System.Threading

printfn "Instantiating two random number generators..."
let rnd1 = Random()
Thread.Sleep 2000
let rnd2 = Random()

printfn "\nThe first random number generator:"
for _ = 1 to 10 do 
    printfn $"   {rnd1.Next()}"

printfn "\nThe second random number generator:"
for _ = 1 to 10 do 
    printfn $"   {rnd2.Next()}"

// The example displays output like the following:
//       Instantiating two random number generators...
//
//       The first random number generator:
//          643164361
//          1606571630
//          1725607587
//          2138048432
//          496874898
//          1969147632
//          2034533749
//          1840964542
//          412380298
//          47518930
//
//       The second random number generator:
//          1251659083
//          1514185439
//          1465798544
//          517841554
//          1821920222
//          195154223
//          1538948391
//          1548375095
//          546062716
//          897797880
Imports System.Threading

Module Example
   Public Sub Main()
      Console.WriteLine("Instantiating two random number generators...")
      Dim rnd1 As New Random()
      Thread.Sleep(2000)
      Dim rnd2 As New Random()
      Console.WriteLine()
      
      Console.WriteLine("The first random number generator:")
      For ctr As Integer = 1 To 10
         Console.WriteLine("   {0}", rnd1.Next())
      Next  
      Console.WriteLine()
       
      Console.WriteLine("The second random number generator:")
      For ctr As Integer = 1 To 10
         Console.WriteLine("   {0}", rnd2.Next())
      Next   
   End Sub
End Module
' The example displays output like the following:
'       Instantiating two random number generators...
'       
'       The first random number generator:
'          643164361
'          1606571630
'          1725607587
'          2138048432
'          496874898
'          1969147632
'          2034533749
'          1840964542
'          412380298
'          47518930
'       
'       The second random number generator:
'          1251659083
'          1514185439
'          1465798544
'          517841554
'          1821920222
'          195154223
'          1538948391
'          1548375095
'          546062716
'          897797880

ただし、その有限の解像度のため、システム クロックは約 15 ミリ秒未満の時間差を検出しません。 したがって、コードで .NET Framework のオーバーロードをRandom()呼び出して 2 つのRandomオブジェクトを連続してインスタンス化すると、誤って同じシード値を持つオブジェクトが提供される可能性があります。 Random(.NET Core の クラスには、この制限はありません)。前の例でこれを確認するには、メソッド呼び出しをThread.Sleepコメントアウトし、この例をもう一度コンパイルして実行します。

この問題を回避するには、複数のオブジェクトではなく、1 つの Random オブジェクトをインスタンス化することをお勧めします。 ただし、 Random スレッド セーフではないため、複数のスレッドからインスタンスにアクセス Random する場合は、同期デバイスを使用する必要があります。詳細については、このトピックの「 Random クラスとスレッド セーフ 」を参照してください。 または、前の例で使用した Sleep メソッドなどの遅延メカニズムを使用して、インスタンス化が 15 ミリ秒を超えて発生することを確認できます。

指定した範囲内の整数を取得する

指定した範囲内の整数を取得するには、 メソッドを Next(Int32, Int32) 呼び出します。これにより、乱数ジェネレーターで返す数値の下限と上限の両方を指定できます。 上限は排他的であり、包括的な値ではありません。 つまり、 メソッドによって返される値の範囲には含まれません。 次の例では、このメソッドを使用して、-10 ~ 10 のランダムな整数を生成します。 メソッド呼び出しの引数の値として、目的の値より 1 大きい 11 を maxValue 指定します。

using namespace System;

void main()
{
   Random^ rnd = gcnew Random();
   for (int ctr = 1; ctr <= 15; ctr++) {
      Console::Write("{0,3}    ", rnd->Next(-10, 11));
      if(ctr % 5 == 0) Console::WriteLine();
   }
}
// The example displays output like the following:
//        -2     -5     -1     -2     10
//        -3      6     -4     -8      3
//        -7     10      5     -2      4
Random rnd = new Random();
for (int ctr = 1; ctr <= 15; ctr++) {
   Console.Write("{0,3}    ", rnd.Next(-10, 11));
   if(ctr % 5 == 0) Console.WriteLine();
}

// The example displays output like the following:
//        -2     -5     -1     -2     10
//        -3      6     -4     -8      3
//        -7     10      5     -2      4
let rnd = Random()
for i = 1 to 15 do 
    printf "%3i    " (rnd.Next(-10, 11))
    if i % 5 = 0 then printfn ""
// The example displays output like the following:
//        -2     -5     -1     -2     10
//        -3      6     -4     -8      3
//        -7     10      5     -2      4
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      For ctr As Integer = 1 To 15
         Console.Write("{0,3}    ", rnd.Next(-10, 11))
         If ctr Mod 5 = 0 Then Console.WriteLine()
      Next   
   End Sub
End Module
' The example displays output like the following:
'        -2     -5     -1     -2     10
'        -3      6     -4     -8      3
'        -7     10      5     -2      4

指定した桁数の整数を取得する

メソッドを Next(Int32, Int32) 呼び出して、指定した桁数の数値を取得できます。 たとえば、4 桁の数字 (つまり、1000 から 9999 までの数値) を取得するには、次の例に示すように、値が 1000 でmaxValue値が 10000 のメソッドminValueを呼び出Next(Int32, Int32)します。

using namespace System;

void main()
{
   Random^ rnd = gcnew Random();
   for (int ctr = 1; ctr <= 50; ctr++) {
      Console::Write("{0,3}   ", rnd->Next(1000, 10000));
      if(ctr % 10 == 0) Console::WriteLine();
   }   
}
// The example displays output like the following:
//    9570    8979    5770    1606    3818    4735    8495    7196    7070    2313
//    5279    6577    5104    5734    4227    3373    7376    6007    8193    5540
//    7558    3934    3819    7392    1113    7191    6947    4963    9179    7907
//    3391    6667    7269    1838    7317    1981    5154    7377    3297    5320
//    9869    8694    2684    4949    2999    3019    2357    5211    9604    2593
Random rnd = new Random();
for (int ctr = 1; ctr <= 50; ctr++) {
   Console.Write("{0,3}    ", rnd.Next(1000, 10000));
   if(ctr % 10 == 0) Console.WriteLine();
}

// The example displays output like the following:
//    9570    8979    5770    1606    3818    4735    8495    7196    7070    2313
//    5279    6577    5104    5734    4227    3373    7376    6007    8193    5540
//    7558    3934    3819    7392    1113    7191    6947    4963    9179    7907
//    3391    6667    7269    1838    7317    1981    5154    7377    3297    5320
//    9869    8694    2684    4949    2999    3019    2357    5211    9604    2593
let rnd = Random()
for i = 1 to 50 do
    printf "%3i    " (rnd.Next(1000, 10000))
    if i % 10 = 0 then printfn ""

// The example displays output like the following:
//    9570    8979    5770    1606    3818    4735    8495    7196    7070    2313
//    5279    6577    5104    5734    4227    3373    7376    6007    8193    5540
//    7558    3934    3819    7392    1113    7191    6947    4963    9179    7907
//    3391    6667    7269    1838    7317    1981    5154    7377    3297    5320
//    9869    8694    2684    4949    2999    3019    2357    5211    9604    2593
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      For ctr As Integer = 1 To 50
         Console.Write("{0,3}    ", rnd.Next(1000, 10000))
         If ctr Mod 10 = 0 Then Console.WriteLine()
      Next   
   End Sub
End Module
' The example displays output like the following:
'    9570    8979    5770    1606    3818    4735    8495    7196    7070    2313
'    5279    6577    5104    5734    4227    3373    7376    6007    8193    5540
'    7558    3934    3819    7392    1113    7191    6947    4963    9179    7907
'    3391    6667    7269    1838    7317    1981    5154    7377    3297    5320
'    9869    8694    2684    4949    2999    3019    2357    5211    9604    2593

指定した範囲内の浮動小数点値を取得する

メソッドは NextDouble 、0 から 1 未満の範囲のランダムな浮動小数点値を返します。 ただし、多くの場合、他の範囲でランダムな値を生成する必要があります。

必要な最小値と最大値の間隔が 1 の場合は、目的の開始間隔と 0 の差を メソッドによって NextDouble 返される数値に追加できます。 次の例では、-1 から 0 までの 10 個の乱数を生成します。

using namespace System;

void main()
{
   Random^ rnd = gcnew Random();
   for (int ctr = 1; ctr <= 10; ctr++)
      Console::WriteLine(rnd->NextDouble() - 1);
}
// The example displays output like the following:
//       -0.930412760437658
//       -0.164699016215605
//       -0.9851692803135
//       -0.43468508843085
//       -0.177202483255976
//       -0.776813320245972
//       -0.0713201854710096
//       -0.0912875561468711
//       -0.540621722368813
//       -0.232211863730201
Random rnd = new Random();
for (int ctr = 1; ctr <= 10; ctr++)
   Console.WriteLine(rnd.NextDouble() - 1);

// The example displays output like the following:
//       -0.930412760437658
//       -0.164699016215605
//       -0.9851692803135
//       -0.43468508843085
//       -0.177202483255976
//       -0.776813320245972
//       -0.0713201854710096
//       -0.0912875561468711
//       -0.540621722368813
//       -0.232211863730201
let rnd = Random()

for _ = 1 to 10 do
    printfn "%O" (rnd.NextDouble() - 1.0)

// The example displays output like the following:
//       -0.930412760437658
//       -0.164699016215605
//       -0.9851692803135
//       -0.43468508843085
//       -0.177202483255976
//       -0.776813320245972
//       -0.0713201854710096
//       -0.0912875561468711
//       -0.540621722368813
//       -0.232211863730201
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      For ctr As Integer = 1 To 10
         Console.WriteLine(rnd.NextDouble() - 1)
      Next
   End Sub
End Module
' The example displays output like the following:
'       -0.930412760437658
'       -0.164699016215605
'       -0.9851692803135
'       -0.43468508843085
'       -0.177202483255976
'       -0.776813320245972
'       -0.0713201854710096
'       -0.0912875561468711
'       -0.540621722368813
'       -0.232211863730201

下限が 0 で上限が 1 より大きいランダム浮動小数点数を生成するには (または、負の数値の場合は下限が -1 未満で、上限が 0 である場合)、乱数に 0 以外のバインドを乗算します。 次の例では、0 から の範囲の 2,000 万個のランダムな浮動小数点数を生成します Int64.MaxValue。 には、 メソッドによって生成されたランダムな値の分布も表示されます。

using namespace System;

void main()
{
   const Int64 ONE_TENTH = 922337203685477581;
   Random^ rnd = gcnew Random();
   double number;
   array<int>^ count = gcnew array<int>(10);
   
   // Generate 20 million integer values between.
   for (int ctr = 1; ctr <= 20000000; ctr++) {
      number = rnd->NextDouble() * Int64::MaxValue;
      // Categorize random numbers into 10 groups.
      int value = (int) (number / ONE_TENTH);
      count[value]++;
   }

   // Display breakdown by range.
   Console::WriteLine("{0,28} {1,32}   {2,7}\n", "Range", "Count", "Pct.");
   for (int ctr = 0; ctr <= 9; ctr++)
      Console::WriteLine("{0,25:N0}-{1,25:N0}  {2,8:N0}   {3,7:P2}", ctr * ONE_TENTH,
                         ctr < 9 ? ctr * ONE_TENTH + ONE_TENTH - 1 : Int64::MaxValue,
                         count[ctr], count[ctr]/20000000.0);
}
// The example displays output like the following:
//                           Range                            Count      Pct.
//    
//                            0-  922,337,203,685,477,580  1,996,148    9.98 %
//      922,337,203,685,477,581-1,844,674,407,370,955,161  2,000,293   10.00 %
//    1,844,674,407,370,955,162-2,767,011,611,056,432,742  2,000,094   10.00 %
//    2,767,011,611,056,432,743-3,689,348,814,741,910,323  2,000,159   10.00 %
//    3,689,348,814,741,910,324-4,611,686,018,427,387,904  1,999,552   10.00 %
//    4,611,686,018,427,387,905-5,534,023,222,112,865,485  1,998,248    9.99 %
//    5,534,023,222,112,865,486-6,456,360,425,798,343,066  2,000,696   10.00 %
//    6,456,360,425,798,343,067-7,378,697,629,483,820,647  2,001,637   10.01 %
//    7,378,697,629,483,820,648-8,301,034,833,169,298,228  2,002,870   10.01 %
//    8,301,034,833,169,298,229-9,223,372,036,854,775,807  2,000,303   10.00 %
const long ONE_TENTH = 922337203685477581;

Random rnd = new Random();
double number;
int[] count = new int[10];

// Generate 20 million integer values between.
for (int ctr = 1; ctr <= 20000000; ctr++) {
   number = rnd.NextDouble() * Int64.MaxValue;
   // Categorize random numbers into 10 groups.
   count[(int) (number / ONE_TENTH)]++;
}
// Display breakdown by range.
Console.WriteLine("{0,28} {1,32}   {2,7}\n", "Range", "Count", "Pct.");
for (int ctr = 0; ctr <= 9; ctr++)
   Console.WriteLine("{0,25:N0}-{1,25:N0}  {2,8:N0}   {3,7:P2}", ctr * ONE_TENTH,
                      ctr < 9 ? ctr * ONE_TENTH + ONE_TENTH - 1 : Int64.MaxValue,
                      count[ctr], count[ctr]/20000000.0);

// The example displays output like the following:
//                           Range                            Count      Pct.
//
//                            0-  922,337,203,685,477,580  1,996,148    9.98 %
//      922,337,203,685,477,581-1,844,674,407,370,955,161  2,000,293   10.00 %
//    1,844,674,407,370,955,162-2,767,011,611,056,432,742  2,000,094   10.00 %
//    2,767,011,611,056,432,743-3,689,348,814,741,910,323  2,000,159   10.00 %
//    3,689,348,814,741,910,324-4,611,686,018,427,387,904  1,999,552   10.00 %
//    4,611,686,018,427,387,905-5,534,023,222,112,865,485  1,998,248    9.99 %
//    5,534,023,222,112,865,486-6,456,360,425,798,343,066  2,000,696   10.00 %
//    6,456,360,425,798,343,067-7,378,697,629,483,820,647  2,001,637   10.01 %
//    7,378,697,629,483,820,648-8,301,034,833,169,298,228  2,002,870   10.01 %
//    8,301,034,833,169,298,229-9,223,372,036,854,775,807  2,000,303   10.00 %
[<Literal>]
let ONE_TENTH = 922337203685477581L

let rnd = Random()

// Generate 20 million random integers.
let count =
    Array.init 20000000 (fun _ -> rnd.NextDouble() * (float Int64.MaxValue) )
    |> Array.countBy (fun x -> x / (float ONE_TENTH) |> int ) // Categorize into 10 groups and count them.
    |> Array.map snd

// Display breakdown by range.
printfn "%28s %32s   %7s\n" "Range" "Count" "Pct."
for i = 0 to 9 do
    let r1 = int64 i * ONE_TENTH
    let r2 = if i < 9 then r1 + ONE_TENTH - 1L else Int64.MaxValue
    printfn $"{r1,25:N0}-{r2,25:N0}  {count.[i],8:N0}   {float count.[i] / 20000000.0,7:P2}"

// The example displays output like the following:
//                           Range                            Count      Pct.
//
//                            0-  922,337,203,685,477,580  1,996,148    9.98 %
//      922,337,203,685,477,581-1,844,674,407,370,955,161  2,000,293   10.00 %
//    1,844,674,407,370,955,162-2,767,011,611,056,432,742  2,000,094   10.00 %
//    2,767,011,611,056,432,743-3,689,348,814,741,910,323  2,000,159   10.00 %
//    3,689,348,814,741,910,324-4,611,686,018,427,387,904  1,999,552   10.00 %
//    4,611,686,018,427,387,905-5,534,023,222,112,865,485  1,998,248    9.99 %
//    5,534,023,222,112,865,486-6,456,360,425,798,343,066  2,000,696   10.00 %
//    6,456,360,425,798,343,067-7,378,697,629,483,820,647  2,001,637   10.01 %
//    7,378,697,629,483,820,648-8,301,034,833,169,298,228  2,002,870   10.01 %
//    8,301,034,833,169,298,229-9,223,372,036,854,775,807  2,000,303   10.00 %
Module Example
   Public Sub Main()
      Const ONE_TENTH As Long = 922337203685477581

      Dim rnd As New Random()
      Dim number As Long
      Dim count(9) As Integer
      
      ' Generate 20 million integer values.
      For ctr As Integer = 1 To 20000000
         number = CLng(rnd.NextDouble() * Int64.MaxValue)
         ' Categorize random numbers.
         count(CInt(number \ ONE_TENTH)) += 1
      Next
      ' Display breakdown by range.
      Console.WriteLine("{0,28} {1,32}   {2,7}", "Range", "Count", "Pct.")
      Console.WriteLine()
      For ctr As Integer = 0 To 9
         Console.WriteLine("{0,25:N0}-{1,25:N0}  {2,8:N0}   {3,7:P2}", ctr * ONE_TENTH,
                            If(ctr < 9, ctr * ONE_TENTH + ONE_TENTH - 1, Int64.MaxValue), 
                            count(ctr), count(ctr)/20000000)
      Next
   End Sub
End Module
' The example displays output like the following:
'                           Range                            Count      Pct.
'    
'                            0-  922,337,203,685,477,580  1,996,148    9.98 %
'      922,337,203,685,477,581-1,844,674,407,370,955,161  2,000,293   10.00 %
'    1,844,674,407,370,955,162-2,767,011,611,056,432,742  2,000,094   10.00 %
'    2,767,011,611,056,432,743-3,689,348,814,741,910,323  2,000,159   10.00 %
'    3,689,348,814,741,910,324-4,611,686,018,427,387,904  1,999,552   10.00 %
'    4,611,686,018,427,387,905-5,534,023,222,112,865,485  1,998,248    9.99 %
'    5,534,023,222,112,865,486-6,456,360,425,798,343,066  2,000,696   10.00 %
'    6,456,360,425,798,343,067-7,378,697,629,483,820,647  2,001,637   10.01 %
'    7,378,697,629,483,820,648-8,301,034,833,169,298,228  2,002,870   10.01 %
'    8,301,034,833,169,298,229-9,223,372,036,854,775,807  2,000,303   10.00 %

メソッドが整数に対して行うのと同様 Next(Int32, Int32) に、2 つの任意の値の間にランダムな浮動小数点数を生成するには、次の数式を使用します。

Random.NextDouble() * (maxValue - minValue) + minValue  

次の例では、10.0 から 11.0 の範囲の 100 万個の乱数を生成し、その分布を表示します。

using namespace System;

void main()
{
   Random^ rnd = gcnew Random();
   int lowerBound = 10;
   int upperBound = 11;
   array<int>^ range = gcnew array<int>(10);
   for (int ctr = 1; ctr <= 1000000; ctr++) {
      Double value = rnd->NextDouble() * (upperBound - lowerBound) + lowerBound;
      range[(int) Math::Truncate((value - lowerBound) * 10)]++;
   }
   
   for (int ctr = 0; ctr <= 9; ctr++) {
      Double lowerRange = 10 + ctr * .1;
      Console::WriteLine("{0:N1} to {1:N1}: {2,8:N0}  ({3,7:P2})",
                         lowerRange, lowerRange + .1, range[ctr],
                         range[ctr] / 1000000.0);
   } 
}
// The example displays output like the following:
//       10.0 to 10.1:   99,929  ( 9.99 %)
//       10.1 to 10.2:  100,189  (10.02 %)
//       10.2 to 10.3:   99,384  ( 9.94 %)
//       10.3 to 10.4:  100,240  (10.02 %)
//       10.4 to 10.5:   99,397  ( 9.94 %)
//       10.5 to 10.6:  100,580  (10.06 %)
//       10.6 to 10.7:  100,293  (10.03 %)
//       10.7 to 10.8:  100,135  (10.01 %)
//       10.8 to 10.9:   99,905  ( 9.99 %)
//       10.9 to 11.0:   99,948  ( 9.99 %)
Random rnd = new Random();
int lowerBound = 10;
int upperBound = 11;
int[] range = new int[10];
for (int ctr = 1; ctr <= 1000000; ctr++) {
   Double value = rnd.NextDouble() * (upperBound - lowerBound) + lowerBound;
   range[(int) Math.Truncate((value - lowerBound) * 10)]++;
}

for (int ctr = 0; ctr <= 9; ctr++) {
   Double lowerRange = 10 + ctr * .1;
   Console.WriteLine("{0:N1} to {1:N1}: {2,8:N0}  ({3,7:P2})",
                     lowerRange, lowerRange + .1, range[ctr],
                     range[ctr] / 1000000.0);
}

// The example displays output like the following:
//       10.0 to 10.1:   99,929  ( 9.99 %)
//       10.1 to 10.2:  100,189  (10.02 %)
//       10.2 to 10.3:   99,384  ( 9.94 %)
//       10.3 to 10.4:  100,240  (10.02 %)
//       10.4 to 10.5:   99,397  ( 9.94 %)
//       10.5 to 10.6:  100,580  (10.06 %)
//       10.6 to 10.7:  100,293  (10.03 %)
//       10.7 to 10.8:  100,135  (10.01 %)
//       10.8 to 10.9:   99,905  ( 9.99 %)
//       10.9 to 11.0:   99,948  ( 9.99 %)
let rnd = Random()

let lowerBound = 10.0
let upperBound = 11.0

let range =
    Array.init 1000000 (fun _ -> rnd.NextDouble() * (upperBound - lowerBound) +  lowerBound)
    |> Array.countBy (fun x -> Math.Truncate((x - lowerBound) * 10.0) |> int)
    |> Array.map snd

for i = 0 to 9 do 
    let lowerRange = 10.0 + float i * 0.1
    printfn $"{lowerRange:N1} to {lowerRange + 0.1:N1}: {range.[i],8:N0}  ({float range.[i] / 1000000.0,6:P2})"

// The example displays output like the following:
//       10.0 to 10.1:   99,929  ( 9.99 %)
//       10.1 to 10.2:  100,189  (10.02 %)
//       10.2 to 10.3:   99,384  ( 9.94 %)
//       10.3 to 10.4:  100,240  (10.02 %)
//       10.4 to 10.5:   99,397  ( 9.94 %)
//       10.5 to 10.6:  100,580  (10.06 %)
//       10.6 to 10.7:  100,293  (10.03 %)
//       10.7 to 10.8:  100,135  (10.01 %)
//       10.8 to 10.9:   99,905  ( 9.99 %)
//       10.9 to 11.0:   99,948  ( 9.99 %)
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      Dim lowerBound As Integer = 10
      Dim upperBound As Integer = 11
      Dim range(9) As Integer
      For ctr As Integer = 1 To 1000000
         Dim value As Double = rnd.NextDouble() * (upperBound - lowerBound) + lowerBound
         range(CInt(Math.Truncate((value - lowerBound) * 10))) += 1 
      Next
      
      For ctr As Integer = 0 To 9
         Dim lowerRange As Double = 10 + ctr * .1
         Console.WriteLine("{0:N1} to {1:N1}: {2,8:N0}  ({3,7:P2})", 
                           lowerRange, lowerRange + .1, range(ctr), 
                           range(ctr) / 1000000.0)
      Next 
   End Sub
End Module
' The example displays output like the following:
'       10.0 to 10.1:   99,929  ( 9.99 %)
'       10.1 to 10.2:  100,189  (10.02 %)
'       10.2 to 10.3:   99,384  ( 9.94 %)
'       10.3 to 10.4:  100,240  (10.02 %)
'       10.4 to 10.5:   99,397  ( 9.94 %)
'       10.5 to 10.6:  100,580  (10.06 %)
'       10.6 to 10.7:  100,293  (10.03 %)
'       10.7 to 10.8:  100,135  (10.01 %)
'       10.8 to 10.9:   99,905  ( 9.99 %)
'       10.9 to 11.0:   99,948  ( 9.99 %)

ランダムなブール値を生成する

クラスには Random 、値を生成 Boolean するメソッドは用意されていません。 ただし、これを行うために独自のクラスまたはメソッドを定義できます。 次の例では、 BooleanGeneratorクラス を 1 つのメソッド NextBooleanで定義します。 クラスは BooleanGenerator 、オブジェクトを Random プライベート変数として格納します。 メソッドは NextBoolean メソッドを Random.Next(Int32, Int32) 呼び出し、結果を メソッドに Convert.ToBoolean(Int32) 渡します。 引数として 2 が使用され、乱数の上限が指定されることに注意してください。 これは排他的な値であるため、メソッド呼び出しは 0 または 1 を返します。

using namespace System;

public ref class BooleanGenerator
{
   private:
      Random^ rnd;

   public:
      BooleanGenerator()
      {
         rnd = gcnew Random();
      }

      bool NextBoolean()
      {
         return Convert::ToBoolean(rnd->Next(0, 2));
      }
};

void main()
{
   // Instantiate the Boolean generator.
   BooleanGenerator^ boolGen = gcnew BooleanGenerator();
   int totalTrue = 0, totalFalse = 0;
   
   // Generate 1,0000 random Booleans, and keep a running total.
   for (int ctr = 0; ctr < 1000000; ctr++) {
       bool value = boolGen->NextBoolean();
       if (value)
          totalTrue++;
       else
          totalFalse++;
   }
   Console::WriteLine("Number of true values:  {0,7:N0} ({1:P3})",
                      totalTrue,
                      ((double) totalTrue)/(totalTrue + totalFalse));
   Console::WriteLine("Number of false values: {0,7:N0} ({1:P3})",
                     totalFalse, 
                     ((double) totalFalse)/(totalTrue + totalFalse));
}

// The example displays output like the following:
//       Number of true values:  500,004 (50.000 %)
//       Number of false values: 499,996 (50.000 %)
using System;

public class Example
{
   public static void Main()
   {
      // Instantiate the Boolean generator.
      BooleanGenerator boolGen = new BooleanGenerator();
      int totalTrue = 0, totalFalse = 0;

      // Generate 1,0000 random Booleans, and keep a running total.
      for (int ctr = 0; ctr < 1000000; ctr++) {
          bool value = boolGen.NextBoolean();
          if (value)
             totalTrue++;
          else
             totalFalse++;
      }
      Console.WriteLine("Number of true values:  {0,7:N0} ({1:P3})",
                        totalTrue,
                        ((double) totalTrue)/(totalTrue + totalFalse));
      Console.WriteLine("Number of false values: {0,7:N0} ({1:P3})",
                        totalFalse,
                        ((double) totalFalse)/(totalTrue + totalFalse));
   }
}

public class BooleanGenerator
{
   Random rnd;

   public BooleanGenerator()
   {
      rnd = new Random();
   }

   public bool NextBoolean()
   {
      return rnd.Next(0, 2) == 1;
   }
}
// The example displays output like the following:
//       Number of true values:  500,004 (50.000 %)
//       Number of false values: 499,996 (50.000 %)
open System

type BooleanGenerator() =
    let rnd = Random()

    member _.NextBoolean() =
        rnd.Next(0, 2) = 1

let boolGen = BooleanGenerator()
let mutable totalTrue, totalFalse = 0, 0

for _ = 1 to 1000000 do
    let value = boolGen.NextBoolean()
    if value then 
        totalTrue <- totalTrue + 1
    else 
        totalFalse <- totalFalse + 1

printfn $"Number of true values:  {totalTrue,7:N0} ({(double totalTrue) / double (totalTrue + totalFalse):P3})"
printfn $"Number of false values: {totalFalse,7:N0} ({(double totalFalse) / double (totalTrue + totalFalse):P3})"

// The example displays output like the following:
//       Number of true values:  500,004 (50.000 %)
//       Number of false values: 499,996 (50.000 %)
Module Example
   Public Sub Main()
      ' Instantiate the Boolean generator.
      Dim boolGen As New BooleanGenerator()
      Dim totalTrue, totalFalse As Integer 
      
      ' Generate 1,0000 random Booleans, and keep a running total.
      For ctr As Integer = 0 To 9999999
          Dim value As Boolean = boolGen.NextBoolean()
          If value Then
             totalTrue += 1
          Else
             totalFalse += 1
          End If
      Next
      Console.WriteLine("Number of true values:  {0,7:N0} ({1:P3})", 
                        totalTrue, 
                        totalTrue/(totalTrue + totalFalse))
      Console.WriteLine("Number of false values: {0,7:N0} ({1:P3})", 
                        totalFalse, 
                        totalFalse/(totalTrue + totalFalse))
   End Sub                     
End Module

Public Class BooleanGenerator
   Dim rnd As Random
   
   Public Sub New()
      rnd = New Random()
   End Sub

   Public Function NextBoolean() As Boolean
      Return Convert.ToBoolean(rnd.Next(0, 2))
   End Function
End Class
' The example displays the following output:
'       Number of true values:  500,004 (50.000 %)
'       Number of false values: 499,996 (50.000 %)

ランダム Boolean な値を生成する別のクラスを作成する代わりに、単に 1 つのメソッドを定義できます。 ただし、その場合、 Random 各メソッド呼び出しで新しい Random インスタンスがインスタンス化されないように、オブジェクトはクラス レベルの変数として定義されている必要があります。 Visual Basic では、Random インスタンスを メソッドの NextBooleanStatic 変数として定義できます。 次の例では、実装を示します。

using namespace System;

ref class Example
{
private:
   static Random^ rnd = gcnew Random();

public:
   static void Execute()
   {
      int totalTrue = 0, totalFalse = 0;
      
      // Generate 1,0000 random Booleans, and keep a running total.
      for (int ctr = 0; ctr < 1000000; ctr++) {
          bool value = NextBoolean();
          if (value)
             totalTrue++;
          else
             totalFalse++;
      }
      Console::WriteLine("Number of true values:  {0,7:N0} ({1:P3})",
                        totalTrue, 
                        ((double) totalTrue)/(totalTrue + totalFalse));
      Console::WriteLine("Number of false values: {0,7:N0} ({1:P3})",
                        totalFalse, 
                        ((double) totalFalse)/(totalTrue + totalFalse));
   }

   static bool NextBoolean()
   {
      return Convert::ToBoolean(rnd->Next(0, 2));
   }
};

void main()
{
   Example::Execute();
}
// The example displays output like the following:
//       Number of true values:  499,777 (49.978 %)
//       Number of false values: 500,223 (50.022 %)
Random rnd = new Random();

int totalTrue = 0, totalFalse = 0;

// Generate 1,000,000 random Booleans, and keep a running total.
for (int ctr = 0; ctr < 1000000; ctr++) {
    bool value = NextBoolean();
    if (value)
       totalTrue++;
    else
       totalFalse++;
}
Console.WriteLine("Number of true values:  {0,7:N0} ({1:P3})",
                  totalTrue,
                  ((double) totalTrue)/(totalTrue + totalFalse));
Console.WriteLine("Number of false values: {0,7:N0} ({1:P3})",
                  totalFalse,
                  ((double) totalFalse)/(totalTrue + totalFalse));

bool NextBoolean()
{
   return rnd.Next(0, 2) == 1;
}

// The example displays output like the following:
//       Number of true values:  499,777 (49.978 %)
//       Number of false values: 500,223 (50.022 %)
let rnd = Random()

let nextBool () =
    rnd.Next(0, 2) = 1

let mutable totalTrue, totalFalse = 0, 0

for _ = 1 to 1000000 do
    let value = nextBool ()
    if value then 
        totalTrue <- totalTrue + 1
    else 
        totalFalse <- totalFalse + 1

printfn $"Number of true values:  {totalTrue,7:N0} ({(double totalTrue) / double (totalTrue + totalFalse):P3})"
printfn $"Number of false values: {totalFalse,7:N0} ({(double totalFalse) / double (totalTrue + totalFalse):P3})"

// The example displays output like the following:
//       Number of true values:  499,777 (49.978 %)
//       Number of false values: 500,223 (50.022 %)
Module Example
   Public Sub Main()
      Dim totalTrue, totalFalse As Integer 
      
      ' Generate 1,0000 random Booleans, and keep a running total.
      For ctr As Integer = 0 To 9999999
          Dim value As Boolean = NextBoolean()
          If value Then
             totalTrue += 1
          Else
             totalFalse += 1
          End If
      Next
      Console.WriteLine("Number of true values:  {0,7:N0} ({1:P3})", 
                        totalTrue, 
                        totalTrue/(totalTrue + totalFalse))
      Console.WriteLine("Number of false values: {0,7:N0} ({1:P3})", 
                        totalFalse, 
                        totalFalse/(totalTrue + totalFalse))
   End Sub 
                       
   Public Function NextBoolean() As Boolean
      Static rnd As New Random()
      Return Convert.ToBoolean(rnd.Next(0, 2))
   End Function
End Module
' The example displays the following output:
'       Number of true values:  499,777 (49.978 %)
'       Number of false values: 500,223 (50.022 %)

ランダムな 64 ビット整数を生成する

メソッドの Next オーバーロードは、32 ビットの整数を返します。 ただし、場合によっては、64 ビット整数を操作する必要があります。 このことは次のように実行できます。

  1. NextDouble倍精度浮動小数点値を取得するには、 メソッドを呼び出します。

  2. その値に を乗算します Int64.MaxValue

次の例では、この手法を使用して 2,000 万個のランダムな長整数を生成し、10 の等しいグループに分類します。 次に、各グループの数値を 0 から にカウントすることで、乱数の分布を Int64.MaxValue評価します。 この例の出力に示すように、数値は長整数の範囲を通じて多かれ少なかれ等しく分散されます。

using namespace System;

void main()
{
   const Int64 ONE_TENTH = 922337203685477581;

   Random^ rnd = gcnew Random();
   Int64 number;
   array<int>^ count = gcnew array<int>(10);
   
   // Generate 20 million long integers.
   for (int ctr = 1; ctr <= 20000000; ctr++) {
      number = (Int64) (rnd->NextDouble() * Int64::MaxValue);
      // Categorize random numbers.
      count[(int) (number / ONE_TENTH)]++;
   }
   // Display breakdown by range.
   Console::WriteLine("{0,28} {1,32}   {2,7}\n", "Range", "Count", "Pct.");
   for (int ctr = 0; ctr <= 9; ctr++)
      Console::WriteLine("{0,25:N0}-{1,25:N0}  {2,8:N0}   {3,7:P2}", ctr * ONE_TENTH,
                         ctr < 9 ? ctr * ONE_TENTH + ONE_TENTH - 1 : Int64::MaxValue,
                         count[ctr], count[ctr]/20000000.0);
}
// The example displays output like the following:
//                           Range                            Count      Pct.
//    
//                            0-  922,337,203,685,477,580  1,996,148    9.98 %
//      922,337,203,685,477,581-1,844,674,407,370,955,161  2,000,293   10.00 %
//    1,844,674,407,370,955,162-2,767,011,611,056,432,742  2,000,094   10.00 %
//    2,767,011,611,056,432,743-3,689,348,814,741,910,323  2,000,159   10.00 %
//    3,689,348,814,741,910,324-4,611,686,018,427,387,904  1,999,552   10.00 %
//    4,611,686,018,427,387,905-5,534,023,222,112,865,485  1,998,248    9.99 %
//    5,534,023,222,112,865,486-6,456,360,425,798,343,066  2,000,696   10.00 %
//    6,456,360,425,798,343,067-7,378,697,629,483,820,647  2,001,637   10.01 %
//    7,378,697,629,483,820,648-8,301,034,833,169,298,228  2,002,870   10.01 %
//    8,301,034,833,169,298,229-9,223,372,036,854,775,807  2,000,303   10.00 %
const long ONE_TENTH = 922337203685477581;

Random rnd = new Random();
long number;
int[] count = new int[10];

// Generate 20 million long integers.
for (int ctr = 1; ctr <= 20000000; ctr++) {
   number = (long) (rnd.NextDouble() * Int64.MaxValue);
   // Categorize random numbers.
   count[(int) (number / ONE_TENTH)]++;
}
// Display breakdown by range.
Console.WriteLine("{0,28} {1,32}   {2,7}\n", "Range", "Count", "Pct.");
for (int ctr = 0; ctr <= 9; ctr++)
   Console.WriteLine("{0,25:N0}-{1,25:N0}  {2,8:N0}   {3,7:P2}", ctr * ONE_TENTH,
                      ctr < 9 ? ctr * ONE_TENTH + ONE_TENTH - 1 : Int64.MaxValue,
                      count[ctr], count[ctr]/20000000.0);

// The example displays output like the following:
//                           Range                            Count      Pct.
//
//                            0-  922,337,203,685,477,580  1,996,148    9.98 %
//      922,337,203,685,477,581-1,844,674,407,370,955,161  2,000,293   10.00 %
//    1,844,674,407,370,955,162-2,767,011,611,056,432,742  2,000,094   10.00 %
//    2,767,011,611,056,432,743-3,689,348,814,741,910,323  2,000,159   10.00 %
//    3,689,348,814,741,910,324-4,611,686,018,427,387,904  1,999,552   10.00 %
//    4,611,686,018,427,387,905-5,534,023,222,112,865,485  1,998,248    9.99 %
//    5,534,023,222,112,865,486-6,456,360,425,798,343,066  2,000,696   10.00 %
//    6,456,360,425,798,343,067-7,378,697,629,483,820,647  2,001,637   10.01 %
//    7,378,697,629,483,820,648-8,301,034,833,169,298,228  2,002,870   10.01 %
//    8,301,034,833,169,298,229-9,223,372,036,854,775,807  2,000,303   10.00 %
[<Literal>]
let ONE_TENTH = 922337203685477581L

let rnd = Random()

let count =
    // Generate 20 million random long integers.
    Array.init 20000000 (fun _ -> rnd.NextDouble() * (float Int64.MaxValue) |> int64 )
    |> Array.countBy (fun x -> x / ONE_TENTH) // Categorize and count random numbers.
    |> Array.map snd

// Display breakdown by range.
printfn "%28s %32s   %7s\n" "Range" "Count" "Pct."
for i = 0 to 9 do
    let r1 = int64 i * ONE_TENTH
    let r2 = if i < 9 then r1 + ONE_TENTH - 1L else Int64.MaxValue
    printfn $"{r1,25:N0}-{r2,25:N0}  {count.[i],8:N0}   {float count.[i] / 20000000.0,7:P2}"

// The example displays output like the following:
//                           Range                            Count      Pct.
//
//                            0-  922,337,203,685,477,580  1,996,148    9.98 %
//      922,337,203,685,477,581-1,844,674,407,370,955,161  2,000,293   10.00 %
//    1,844,674,407,370,955,162-2,767,011,611,056,432,742  2,000,094   10.00 %
//    2,767,011,611,056,432,743-3,689,348,814,741,910,323  2,000,159   10.00 %
//    3,689,348,814,741,910,324-4,611,686,018,427,387,904  1,999,552   10.00 %
//    4,611,686,018,427,387,905-5,534,023,222,112,865,485  1,998,248    9.99 %
//    5,534,023,222,112,865,486-6,456,360,425,798,343,066  2,000,696   10.00 %
//    6,456,360,425,798,343,067-7,378,697,629,483,820,647  2,001,637   10.01 %
//    7,378,697,629,483,820,648-8,301,034,833,169,298,228  2,002,870   10.01 %
//    8,301,034,833,169,298,229-9,223,372,036,854,775,807  2,000,303   10.00 %
Module Example
   Public Sub Main()
      Const ONE_TENTH As Long = 922337203685477581

      Dim rnd As New Random()
      Dim number As Long
      Dim count(9) As Integer
      
      ' Generate 20 million long integers.
      For ctr As Integer = 1 To 20000000
         number = CLng(rnd.NextDouble() * Int64.MaxValue)
         ' Categorize random numbers.
         count(CInt(number \ ONE_TENTH)) += 1
      Next
      ' Display breakdown by range.
      Console.WriteLine("{0,28} {1,32}   {2,7}", "Range", "Count", "Pct.")
      Console.WriteLine()
      For ctr As Integer = 0 To 9
         Console.WriteLine("{0,25:N0}-{1,25:N0}  {2,8:N0}   {3,7:P2}", ctr * ONE_TENTH,
                            If(ctr < 9, ctr * ONE_TENTH + ONE_TENTH - 1, Int64.MaxValue), 
                            count(ctr), count(ctr)/20000000)
      Next
   End Sub
End Module
' The example displays output like the following:
'                           Range                            Count      Pct.
'    
'                            0-  922,337,203,685,477,580  1,996,148    9.98 %
'      922,337,203,685,477,581-1,844,674,407,370,955,161  2,000,293   10.00 %
'    1,844,674,407,370,955,162-2,767,011,611,056,432,742  2,000,094   10.00 %
'    2,767,011,611,056,432,743-3,689,348,814,741,910,323  2,000,159   10.00 %
'    3,689,348,814,741,910,324-4,611,686,018,427,387,904  1,999,552   10.00 %
'    4,611,686,018,427,387,905-5,534,023,222,112,865,485  1,998,248    9.99 %
'    5,534,023,222,112,865,486-6,456,360,425,798,343,066  2,000,696   10.00 %
'    6,456,360,425,798,343,067-7,378,697,629,483,820,647  2,001,637   10.01 %
'    7,378,697,629,483,820,648-8,301,034,833,169,298,228  2,002,870   10.01 %
'    8,301,034,833,169,298,229-9,223,372,036,854,775,807  2,000,303   10.00 %

ビット操作を使用する別の手法では、真に乱数は生成されません。 この手法では、 を呼び出 Next() して 2 つの整数を生成し、左シフトを 1 ビットずつ 32 ビットずつシフトし、それらの整数を一緒に生成します。 この手法には、次の 2 つの制限があります。

  1. ビット 31 は符号ビットであるため、結果の長整数のビット 31 の値は常に 0 です。 これは、ランダムな 0 または 1 を生成し、31 ビット左シフトし、元のランダムな長整数で ORing することで対処できます。

  2. もっと真剣に言うと、 によって Next() 返される値が 0 になる確率が 0 であるため、範囲内の乱数が0x0 0x00000000FFFFFFFF場合は少なくなります。

指定した範囲内のバイトを取得する

メソッドの Next オーバーロードを使用すると、乱数の範囲を指定できますが NextBytes 、メソッドでは指定できません。 次の例では、 NextBytes 返されるバイトの範囲を指定できる メソッドを実装します。 から派生し、Random2そのNextBytesメソッドをRandomオーバーロードするクラスを定義します。

using namespace System;

ref class Random2 : Random
{
public:
   Random2()
   {}

   Random2(int seed) : Random(seed)
   {}

   void NextBytes(array<Byte>^ bytes, Byte minValue, Byte maxValue)
   {
      for (int ctr = bytes->GetLowerBound(0); ctr <= bytes->GetUpperBound(0); ctr++)
         bytes[ctr] = (Byte) Next(minValue, maxValue);
   }
};

void main()
{
    Random2^ rnd = gcnew Random2();
    array<Byte>^ bytes = gcnew array<Byte>(10000);
    array<int>^ total = gcnew array<int>(101);
    rnd->NextBytes(bytes, 0, 101);

    // Calculate how many of each value we have.
    for each (Byte value in bytes)
       total[value]++;

    // Display the results.
    for (int ctr = 0; ctr < total->Length; ctr++) {
        Console::Write("{0,3}: {1,-3}   ", ctr, total[ctr]);
        if ((ctr + 1) % 5 == 0) Console::WriteLine();
    }
}
// The example displays output like the following:
//         0: 115     1: 119     2: 92      3: 98      4: 92
//         5: 102     6: 103     7: 84      8: 93      9: 116
//        10: 91     11: 98     12: 106    13: 91     14: 92
//        15: 101    16: 100    17: 96     18: 97     19: 100
//        20: 101    21: 106    22: 112    23: 82     24: 85
//        25: 102    26: 107    27: 98     28: 106    29: 102
//        30: 109    31: 108    32: 94     33: 101    34: 107
//        35: 101    36: 86     37: 100    38: 101    39: 102
//        40: 113    41: 95     42: 96     43: 89     44: 99
//        45: 81     46: 89     47: 105    48: 100    49: 85
//        50: 103    51: 103    52: 93     53: 89     54: 91
//        55: 97     56: 105    57: 97     58: 110    59: 86
//        60: 116    61: 94     62: 117    63: 98     64: 110
//        65: 93     66: 102    67: 100    68: 105    69: 83
//        70: 81     71: 97     72: 85     73: 70     74: 98
//        75: 100    76: 110    77: 114    78: 83     79: 90
//        80: 96     81: 112    82: 102    83: 102    84: 99
//        85: 81     86: 100    87: 93     88: 99     89: 118
//        90: 95     91: 124    92: 108    93: 96     94: 104
//        95: 106    96: 99     97: 99     98: 92     99: 99
//       100: 108
using System;

public class Example
{
   public static void Main()
   {
       Random2 rnd = new Random2();
       Byte[] bytes = new Byte[10000];
       int[] total = new int[101];
       rnd.NextBytes(bytes, 0, 101);

       // Calculate how many of each value we have.
       foreach (var value in bytes)
          total[value]++;

       // Display the results.
       for (int ctr = 0; ctr < total.Length; ctr++) {
           Console.Write("{0,3}: {1,-3}   ", ctr, total[ctr]);
           if ((ctr + 1) % 5 == 0) Console.WriteLine();
       }
   }
}

public class Random2 : Random
{
   public Random2() : base()
   {}

   public Random2(int seed) : base(seed)
   {}

   public void NextBytes(byte[] bytes, byte minValue, byte maxValue)
   {
      for (int ctr = bytes.GetLowerBound(0); ctr <= bytes.GetUpperBound(0); ctr++)
         bytes[ctr] = (byte) Next(minValue, maxValue);
   }
}
// The example displays output like the following:
//         0: 115     1: 119     2: 92      3: 98      4: 92
//         5: 102     6: 103     7: 84      8: 93      9: 116
//        10: 91     11: 98     12: 106    13: 91     14: 92
//        15: 101    16: 100    17: 96     18: 97     19: 100
//        20: 101    21: 106    22: 112    23: 82     24: 85
//        25: 102    26: 107    27: 98     28: 106    29: 102
//        30: 109    31: 108    32: 94     33: 101    34: 107
//        35: 101    36: 86     37: 100    38: 101    39: 102
//        40: 113    41: 95     42: 96     43: 89     44: 99
//        45: 81     46: 89     47: 105    48: 100    49: 85
//        50: 103    51: 103    52: 93     53: 89     54: 91
//        55: 97     56: 105    57: 97     58: 110    59: 86
//        60: 116    61: 94     62: 117    63: 98     64: 110
//        65: 93     66: 102    67: 100    68: 105    69: 83
//        70: 81     71: 97     72: 85     73: 70     74: 98
//        75: 100    76: 110    77: 114    78: 83     79: 90
//        80: 96     81: 112    82: 102    83: 102    84: 99
//        85: 81     86: 100    87: 93     88: 99     89: 118
//        90: 95     91: 124    92: 108    93: 96     94: 104
//        95: 106    96: 99     97: 99     98: 92     99: 99
//       100: 108
open System

type Random2() =
    inherit Random()

    member this.NextBytes(bytes: byte[], minValue: byte, maxValue: byte) =
        for i=bytes.GetLowerBound(0) to bytes.GetUpperBound(0) do
            bytes.[i] <- this.Next(int minValue, int maxValue) |> byte

let rnd = Random2()
let bytes = Array.zeroCreate 10000
let total = Array.zeroCreate 101
rnd.NextBytes(bytes, 0uy, 101uy)

// Calculate how many of each value we have.
for v in bytes do 
    total.[int v] <- total.[int v] + 1

// Display the results.
for i = 0 to total.Length - 1 do
    printf "%3i: %-3i   " i total.[i]
    if (i + 1) % 5 = 0 then printfn ""

// The example displays output like the following:
//         0: 115     1: 119     2: 92      3: 98      4: 92
//         5: 102     6: 103     7: 84      8: 93      9: 116
//        10: 91     11: 98     12: 106    13: 91     14: 92
//        15: 101    16: 100    17: 96     18: 97     19: 100
//        20: 101    21: 106    22: 112    23: 82     24: 85
//        25: 102    26: 107    27: 98     28: 106    29: 102
//        30: 109    31: 108    32: 94     33: 101    34: 107
//        35: 101    36: 86     37: 100    38: 101    39: 102
//        40: 113    41: 95     42: 96     43: 89     44: 99
//        45: 81     46: 89     47: 105    48: 100    49: 85
//        50: 103    51: 103    52: 93     53: 89     54: 91
//        55: 97     56: 105    57: 97     58: 110    59: 86
//        60: 116    61: 94     62: 117    63: 98     64: 110
//        65: 93     66: 102    67: 100    68: 105    69: 83
//        70: 81     71: 97     72: 85     73: 70     74: 98
//        75: 100    76: 110    77: 114    78: 83     79: 90
//        80: 96     81: 112    82: 102    83: 102    84: 99
//        85: 81     86: 100    87: 93     88: 99     89: 118
//        90: 95     91: 124    92: 108    93: 96     94: 104
//        95: 106    96: 99     97: 99     98: 92     99: 99
//       100: 108
Module Example
   Public Sub Main()
       Dim rnd As New Random2()
       Dim bytes(9999) As Byte
       Dim total(100) As Integer
       rnd.NextBytes(bytes, 0, 101)
       
       ' Calculate how many of each value we have.
       For Each value In bytes
          total(value) += 1
       Next
       
       ' Display the results.
       For ctr As Integer = 0 To total.Length - 1
           Console.Write("{0,3}: {1,-3}   ", ctr, total(ctr))
           If (ctr + 1) Mod 5 = 0 Then Console.WriteLine()
       Next   
   End Sub
End Module

Public Class Random2 : Inherits Random
   Public Sub New()
      MyBase.New()
   End Sub   

   Public Sub New(seed As Integer)
      MyBase.New(seed)
   End Sub

   Public Overloads Sub NextBytes(bytes() As Byte, 
                                  minValue As Byte, maxValue As Byte)
      For ctr As Integer = bytes.GetLowerbound(0) To bytes.GetUpperBound(0)
         bytes(ctr) = CByte(MyBase.Next(minValue, maxValue))
      Next
   End Sub
End Class 
' The example displays output like the following:
'         0: 115     1: 119     2: 92      3: 98      4: 92
'         5: 102     6: 103     7: 84      8: 93      9: 116
'        10: 91     11: 98     12: 106    13: 91     14: 92
'        15: 101    16: 100    17: 96     18: 97     19: 100
'        20: 101    21: 106    22: 112    23: 82     24: 85
'        25: 102    26: 107    27: 98     28: 106    29: 102
'        30: 109    31: 108    32: 94     33: 101    34: 107
'        35: 101    36: 86     37: 100    38: 101    39: 102
'        40: 113    41: 95     42: 96     43: 89     44: 99
'        45: 81     46: 89     47: 105    48: 100    49: 85
'        50: 103    51: 103    52: 93     53: 89     54: 91
'        55: 97     56: 105    57: 97     58: 110    59: 86
'        60: 116    61: 94     62: 117    63: 98     64: 110
'        65: 93     66: 102    67: 100    68: 105    69: 83
'        70: 81     71: 97     72: 85     73: 70     74: 98
'        75: 100    76: 110    77: 114    78: 83     79: 90
'        80: 96     81: 112    82: 102    83: 102    84: 99
'        85: 81     86: 100    87: 93     88: 99     89: 118
'        90: 95     91: 124    92: 108    93: 96     94: 104
'        95: 106    96: 99     97: 99     98: 92     99: 99
'       100: 108

メソッドは NextBytes(Byte[], Byte, Byte) メソッドの呼び出しを Next(Int32, Int32) ラップし、バイト配列で返される最大値 (この場合は 0 と 101) より大きい最小値と 1 つを指定します。 メソッドによって Next 返される整数値がデータ型の Byte 範囲内にあることが確実であるため、(C# と F#では) 安全にキャストすることも、(Visual Basic では) 整数からバイトに変換することもできます。

配列またはコレクションからランダムに要素を取得する

乱数は、多くの場合、配列またはコレクションから値を取得するためのインデックスとして機能します。 ランダムインデックス値を取得するには、 メソッドを Next(Int32, Int32) 呼び出し、配列の下限を minValue 引数の値として使用し、配列の上限より大きい値を maxValue 引数の値として使用します。 0 から始まる配列の場合、これはプロパティ Length と同じか、 メソッドによって Array.GetUpperBound 返される値より 1 大きい値です。 次の例では、都市の配列から、米国内の都市の名前をランダムに取得します。

using namespace System;

void main()
{
   array<String^>^ cities = { "Atlanta", "Boston", "Chicago", "Detroit",
                              "Fort Wayne", "Greensboro", "Honolulu", "Indianapolis",
                              "Jersey City", "Kansas City", "Los Angeles",
                              "Milwaukee", "New York", "Omaha", "Philadelphia",
                              "Raleigh", "San Francisco", "Tulsa", "Washington" };
   Random^ rnd = gcnew Random();
   int index = rnd->Next(0, cities->Length);
   Console::WriteLine("Today's city of the day: {0}",
                      cities[index]);
}
// The example displays output like the following:
//   Today's city of the day: Honolulu
String[] cities = { "Atlanta", "Boston", "Chicago", "Detroit",
                    "Fort Wayne", "Greensboro", "Honolulu", "Indianapolis",
                    "Jersey City", "Kansas City", "Los Angeles",
                    "Milwaukee", "New York", "Omaha", "Philadelphia",
                    "Raleigh", "San Francisco", "Tulsa", "Washington" };
Random rnd = new Random();
int index = rnd.Next(0, cities.Length);
Console.WriteLine("Today's city of the day: {0}",
                  cities[index]);

// The example displays output like the following:
//   Today's city of the day: Honolulu
let cities = 
    [| "Atlanta"; "Boston"; "Chicago"; "Detroit";
       "Fort Wayne"; "Greensboro"; "Honolulu"; "Indianapolis";
       "Jersey City"; "Kansas City"; "Los Angeles";
       "Milwaukee"; "New York"; "Omaha"; "Philadelphia";
       "Raleigh"; "San Francisco"; "Tulsa"; "Washington" |]

let rnd = Random()

let index = rnd.Next(0,cities.Length)

printfn "Today's city of the day: %s" cities.[index]

// The example displays output like the following:
//   Today's city of the day: Honolulu
Module Example
   Public Sub Main()
      Dim cities() As String = { "Atlanta", "Boston", "Chicago", "Detroit", 
                                 "Fort Wayne", "Greensboro", "Honolulu", "Indianapolis", 
                                 "Jersey City", "Kansas City", "Los Angeles", 
                                 "Milwaukee", "New York", "Omaha", "Philadelphia", 
                                 "Raleigh", "San Francisco", "Tulsa", "Washington" }
      Dim rnd As New Random()
      Dim index As Integer = rnd.Next(0, cities.Length)
      Console.WriteLine("Today's city of the day: {0}",
                        cities(index))                           
   End Sub
End Module
' The example displays output like the following:
'   Today's city of the day: Honolulu

配列またはコレクションから一意の要素を取得する

乱数ジェネレーターは、常に重複する値を返すことができます。 数値の範囲が小さくなったり、生成される値の数が大きくなると、重複する可能性が高くなります。 ランダムな値を一意にする必要がある場合、重複を補正するために生成される数値が増え、パフォーマンスが低下します。

このシナリオを処理するには、いくつかの手法があります。 一般的な解決策の 1 つは、取得する値を含む配列またはコレクションと、ランダムな浮動小数点数を含む並列配列を作成することです。 2 番目の配列には、最初の配列の作成時に乱数が設定され Array.Sort(Array, Array) 、 メソッドを使用して、並列配列の値を使用して最初の配列を並べ替えます。

たとえば、ソリティア ゲームを開発している場合は、各カードが 1 回だけ使用されるようにする必要があります。 乱数を生成してカードを取得し、そのカードが既に処理されているかどうかを追跡する代わりに、デッキの並べ替えに使用できる乱数の並列配列を作成できます。 デッキが並べ替えられると、アプリはポインターを維持して、デッキ上の次のカードのインデックスを示すことができます。

このアプローチの例を次に示します。 再生中のCardカードを表すクラスと、Dealerシャッフルされたカードのデッキを処理するクラスを定義します。 クラス コンストラクターはDealerdeckクラス スコープを持ち、デッキ内のすべてのカードを表す配列と、配列と同じ数の要素deckを持ち、ランダムに生成されたDouble値が設定されたローカルorder配列の 2 つの配列を設定します。 Array.Sort(Array, Array)次に、 メソッドが呼び出され、配列内のdeck値に基づいて配列がorder並べ替えられます。

using namespace System;

public enum class Suit { Hearts, Diamonds, Spades, Clubs };

public enum class FaceValue  { Ace = 1, Two, Three, Four, Five, Six,
                               Seven, Eight, Nine, Ten, Jack, Queen,
                               King };

// A class that represents an individual card in a playing deck.
ref class Card
{
public:
   Suit Suit;
   FaceValue FaceValue;
   
   String^ ToString() override
   {
      return String::Format("{0:F} of {1:F}", this->FaceValue, this->Suit);
   }
};

ref class Dealer
{
private:
   Random^ rnd;
   // A deck of cards, without Jokers.
   array<Card^>^ deck = gcnew array<Card^>(52);
   // Parallel array for sorting cards.
   array<Double>^ order = gcnew array<Double>(52);
   // A pointer to the next card to deal.
   int ptr = 0;
   // A flag to indicate the deck is used.
   bool mustReshuffle = false;
   
public:
   Dealer()
   {
      rnd = gcnew Random();
      // Initialize the deck.
      int deckCtr = 0;
      for each (auto suit in Enum::GetValues(Suit::typeid)) {
         for each (FaceValue faceValue in Enum::GetValues(FaceValue::typeid)) {
            Card^ card = gcnew Card();
            card->Suit = (Suit) suit;
            card->FaceValue = (FaceValue) faceValue;
            deck[deckCtr] = card;  
            deckCtr++;
         }
      }
      
      for (int ctr = 0; ctr < order->Length; ctr++)
         order[ctr] = rnd->NextDouble();

      Array::Sort(order, deck);
   }

   array<Card^>^ Deal(int numberToDeal)
   {
      if (mustReshuffle) {
         Console::WriteLine("There are no cards left in the deck");
         return nullptr;
      }
      
      array<Card^>^ cardsDealt = gcnew array<Card^>(numberToDeal);
      for (int ctr = 0; ctr < numberToDeal; ctr++) {
         cardsDealt[ctr] = deck[ptr];
         ptr++;
         if (ptr == deck->Length)
            mustReshuffle = true;

         if (mustReshuffle & ctr < numberToDeal - 1) {
            Console::WriteLine("Can only deal the {0} cards remaining on the deck.",
                               ctr + 1);
            return cardsDealt;
         }
      }
      return cardsDealt;
   }
};

void ShowCards(array<Card^>^ cards)
{
   for each (Card^ card in cards)
      if (card != nullptr)
         Console::WriteLine("{0} of {1}", card->FaceValue, card->Suit);
};

void main()
{
   Dealer^ dealer = gcnew Dealer();
   ShowCards(dealer->Deal(20));
}

// The example displays output like the following:
//       Six of Diamonds
//       King of Clubs
//       Eight of Clubs
//       Seven of Clubs
//       Queen of Clubs
//       King of Hearts
//       Three of Spades
//       Ace of Clubs
//       Four of Hearts
//       Three of Diamonds
//       Nine of Diamonds
//       Two of Hearts
//       Ace of Hearts
//       Three of Hearts
//       Four of Spades
//       Eight of Hearts
//       Queen of Diamonds
//       Two of Clubs
//       Four of Diamonds
//       Jack of Hearts
using System;

// A class that represents an individual card in a playing deck.
public class Card
{
   public Suit Suit;
   public FaceValue FaceValue;

   public override String ToString()
   {
      return String.Format("{0:F} of {1:F}", this.FaceValue, this.Suit);
   }
}

public enum Suit { Hearts, Diamonds, Spades, Clubs };

public enum FaceValue  { Ace = 1, Two, Three, Four, Five, Six,
                         Seven, Eight, Nine, Ten, Jack, Queen,
                         King };

public class Dealer
{
   Random rnd;
   // A deck of cards, without Jokers.
   Card[] deck = new Card[52];
   // Parallel array for sorting cards.
   Double[] order = new Double[52];
   // A pointer to the next card to deal.
   int ptr = 0;
   // A flag to indicate the deck is used.
   bool mustReshuffle = false;

   public Dealer()
   {
      rnd = new Random();
      // Initialize the deck.
      int deckCtr = 0;
      foreach (var suit in Enum.GetValues(typeof(Suit))) {
         foreach (var faceValue in Enum.GetValues(typeof(FaceValue))) {
            Card card = new Card();
            card.Suit = (Suit) suit;
            card.FaceValue = (FaceValue) faceValue;
            deck[deckCtr] = card;
            deckCtr++;
         }
      }

      for (int ctr = 0; ctr < order.Length; ctr++)
         order[ctr] = rnd.NextDouble();

      Array.Sort(order, deck);
   }

   public Card[] Deal(int numberToDeal)
   {
      if (mustReshuffle) {
         Console.WriteLine("There are no cards left in the deck");
         return null;
      }

      Card[] cardsDealt = new Card[numberToDeal];
      for (int ctr = 0; ctr < numberToDeal; ctr++) {
         cardsDealt[ctr] = deck[ptr];
         ptr++;
         if (ptr == deck.Length)
            mustReshuffle = true;

         if (mustReshuffle & ctr < numberToDeal - 1) {
            Console.WriteLine("Can only deal the {0} cards remaining on the deck.",
                              ctr + 1);
            return cardsDealt;
         }
      }
      return cardsDealt;
   }
}

public class Example
{
   public static void Main()
   {
      Dealer dealer = new Dealer();
      ShowCards(dealer.Deal(20));
   }

   private static void ShowCards(Card[] cards)
   {
      foreach (var card in cards)
         if (card != null)
            Console.WriteLine("{0} of {1}", card.FaceValue, card.Suit);
   }
}
// The example displays output like the following:
//       Six of Diamonds
//       King of Clubs
//       Eight of Clubs
//       Seven of Clubs
//       Queen of Clubs
//       King of Hearts
//       Three of Spades
//       Ace of Clubs
//       Four of Hearts
//       Three of Diamonds
//       Nine of Diamonds
//       Two of Hearts
//       Ace of Hearts
//       Three of Hearts
//       Four of Spades
//       Eight of Hearts
//       Queen of Diamonds
//       Two of Clubs
//       Four of Diamonds
//       Jack of Hearts
open System

type Suit =
    | Clubs
    | Diamonds
    | Hearts
    | Spades

type Face =
    | Ace | Two | Three
    | Four | Five | Six
    | Seven | Eight | Nine
    | Ten | Jack | Queen | King

type Card = { Face: Face; Suit: Suit }

let suits = [ Clubs; Diamonds; Hearts; Spades ]
let faces = [ Ace; Two; Three; Four; Five; Six; Seven; Eight; Nine; Ten; Jack; Queen; King ]

type Dealer() =
    let rnd = Random()
    let mutable pos = 0
    // Parallel array for sorting cards.
    let order = Array.init (suits.Length * faces.Length) (fun _ -> rnd.NextDouble() )
    // A deck of cards, without Jokers.
    let deck = [|
        for s in suits do
            for f in faces do
                { Face = f; Suit = s } |]
    // Shuffle the deck.
    do Array.Sort(order, deck)

    // Deal a number of cards from the deck, return None if failed
    member _.Deal(numberToDeal) : Card [] option = 
        if numberToDeal = 0 || pos = deck.Length then
            printfn "There are no cards left in the deck"
            None
        else 
            let cards = deck.[pos .. numberToDeal + pos - 1]
            if numberToDeal > deck.Length - pos then
                printfn "Can only deal the %i cards remaining on the deck." (deck.Length - pos)
            pos <- min (pos + numberToDeal) deck.Length
            Some cards

let showCards cards = 
    for card in cards do
        printfn $"{card.Face} of {card.Suit}"

let dealer = Dealer()

dealer.Deal 20
|> Option.iter showCards

// The example displays output like the following:
//       Six of Diamonds
//       King of Clubs
//       Eight of Clubs
//       Seven of Clubs
//       Queen of Clubs
//       King of Hearts
//       Three of Spades
//       Ace of Clubs
//       Four of Hearts
//       Three of Diamonds
//       Nine of Diamonds
//       Two of Hearts
//       Ace of Hearts
//       Three of Hearts
//       Four of Spades
//       Eight of Hearts
//       Queen of Diamonds
//       Two of Clubs
//       Four of Diamonds
//       Jack of Hearts
' A class that represents an individual card in a playing deck.
Public Class Card
   Public Suit As Suit
   Public FaceValue As FaceValue
   
   Public Overrides Function ToString() As String
      Return String.Format("{0:F} of {1:F}", Me.FaceValue, Me.Suit)
   End Function
End Class

Public Enum Suit As Integer
   Hearts = 0
   Diamonds = 1
   Spades = 2
   Clubs = 3
End Enum

Public Enum FaceValue As Integer
   Ace = 1
   Two = 2
   Three = 3
   Four = 4
   Five = 5
   Six = 6
   Seven = 7
   Eight = 8
   Nine = 9
   Ten = 10
   Jack = 11
   Queen = 12
   King = 13
End Enum

Public Class Dealer
   Dim rnd As Random
   ' A deck of cards, without Jokers.
   Dim deck(51) As Card
   ' Parallel array for sorting cards.
   Dim order(51) As Double
   ' A pointer to the next card to deal.
   Dim ptr As Integer = 0
   ' A flag to indicate the deck is used.
   Dim mustReshuffle As Boolean
   
   Public Sub New()
      rnd = New Random()
      ' Initialize the deck.
      Dim deckCtr As Integer = 0
      For Each Suit In [Enum].GetValues(GetType(Suit))
         For Each faceValue In [Enum].GetValues(GetType(FaceValue))
            Dim card As New Card()
            card.Suit = CType(Suit, Suit)
            card.FaceValue = CType(faceValue, FaceValue)
            deck(deckCtr) = card  
            deckCtr += 1
         Next
      Next
      For ctr As Integer = 0 To order.Length - 1
         order(ctr) = rnd.NextDouble()   
      Next   
      Array.Sort(order, deck)
   End Sub

   Public Function Deal(numberToDeal As Integer) As Card()
      If mustReshuffle Then
         Console.WriteLine("There are no cards left in the deck")
         Return Nothing
      End If
      
      Dim cardsDealt(numberToDeal - 1) As Card
      For ctr As Integer = 0 To numberToDeal - 1
         cardsDealt(ctr) = deck(ptr)
         ptr += 1
         If ptr = deck.Length Then 
            mustReshuffle = True
         End If
         If mustReshuffle And ctr < numberToDeal - 1
            Console.WriteLine("Can only deal the {0} cards remaining on the deck.", 
                              ctr + 1)
            Return cardsDealt
         End If
      Next
      Return cardsDealt
   End Function
End Class

Public Module Example
   Public Sub Main()
      Dim dealer As New Dealer()
      ShowCards(dealer.Deal(20))
   End Sub
   
   Private Sub ShowCards(cards() As Card)
      For Each card In cards
         If card IsNot Nothing Then _
            Console.WriteLine("{0} of {1}", card.FaceValue, card.Suit)
      Next
   End Sub
End Module
' The example displays output like the following:
'       Six of Diamonds
'       King of Clubs
'       Eight of Clubs
'       Seven of Clubs
'       Queen of Clubs
'       King of Hearts
'       Three of Spades
'       Ace of Clubs
'       Four of Hearts
'       Three of Diamonds
'       Nine of Diamonds
'       Two of Hearts
'       Ace of Hearts
'       Three of Hearts
'       Four of Spades
'       Eight of Hearts
'       Queen of Diamonds
'       Two of Clubs
'       Four of Diamonds
'       Jack of Hearts

注意 (継承者)

.NET Framework 1.0 および 1.1 では、乱数を生成するための新しいアルゴリズムまたは変更されたアルゴリズムを定義するために、 メソッドをSample()オーバーライドする必要からRandom派生したクラスの最小実装。 その後、派生クラスは、、、および NextDouble() メソッドの基底クラスのNext(Int32)Next()Next(Int32, Int32)実装に依存して、 メソッドの派生クラスの実装をSample()呼び出す可能性があります。 NextBytes(Byte[])

.NET Framework 2.0 以降では、、、および NextBytes(Byte[]) メソッドのNext()Next(Int32, Int32)動作が変更され、これらのメソッドが必ずしも メソッドの派生クラスの実装をSample()呼び出すわけではありません。 その結果、.NET Framework 2.0 以降を対象とする からRandom派生したクラスは、これら 3 つのメソッドもオーバーライドする必要があります。

注意 (呼び出し元)

クラスの乱数ジェネレーターRandomの実装は、.NET Frameworkのメジャー バージョン間で同じままであるとは限りません。 その結果、同じシードが異なるバージョンの.NET Frameworkで同じ擬似ランダム シーケンスになるとは想定しないでください。

コンストラクター

Random()

既定のシード値を使用して Random クラスの新しいインスタンスを初期化します。

Random(Int32)

指定したシード値を使用して Random クラスの新しいインスタンスを初期化します。

プロパティ

Shared

任意のスレッドから同時に使用できるスレッド セーフ Random なインスタンスを提供します。

メソッド

Equals(Object)

指定されたオブジェクトが現在のオブジェクトと等しいかどうかを判断します。

(継承元 Object)
GetHashCode()

既定のハッシュ関数として機能します。

(継承元 Object)
GetItems<T>(ReadOnlySpan<T>, Int32)

指定された選択肢のセットからランダムに選択された項目が設定された配列を作成します。

GetItems<T>(ReadOnlySpan<T>, Span<T>)

指定したスパンの要素に、指定した選択肢のセットからランダムに選択された項目を入力します。

GetItems<T>(T[], Int32)

指定された選択肢のセットからランダムに選択された項目が設定された配列を作成します。

GetType()

現在のインスタンスの Type を取得します。

(継承元 Object)
MemberwiseClone()

現在の Object の簡易コピーを作成します。

(継承元 Object)
Next()

0 以上のランダムな整数を返します。

Next(Int32)

指定した最大値より小さい 0 以上のランダムな整数を返します。

Next(Int32, Int32)

指定した範囲内のランダムな整数を返します。

NextBytes(Byte[])

指定したバイト配列の要素に乱数を格納します。

NextBytes(Span<Byte>)

指定したバイト範囲の要素に乱数を格納します。

NextDouble()

0.0 以上 1.0 未満のランダムな浮動小数点数を返します。

NextInt64()

0 以上のランダムな整数を返します。

NextInt64(Int64)

指定した最大値より小さい 0 以上のランダムな整数を返します。

NextInt64(Int64, Int64)

指定した範囲内のランダムな整数を返します。

NextSingle()

0.0 以上 1.0 未満のランダムな浮動小数点数を返します。

Sample()

0.0 と 1.0 の間のランダムな浮動小数点数を返します。

Shuffle<T>(Span<T>)

スパンのインプレース シャッフルを実行します。

Shuffle<T>(T[])

配列のインプレース シャッフルを実行します。

ToString()

現在のオブジェクトを表す文字列を返します。

(継承元 Object)

適用対象