Random Sınıf

Tanım

Rastgelelik için belirli istatistiksel gereksinimleri karşılayan bir sayı dizisi oluşturan bir algoritma olan sahte-rastgele sayı oluşturucusunun temsilidir.

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
Devralma
Random
Öznitelikler

Örnekler

Aşağıdaki örnek tek bir rastgele sayı oluşturucu oluşturur ve farklı aralıklarda rastgele sayı dizileri oluşturmak için , NextBytesNextve NextDouble yöntemlerini çağırır.

// Instantiate random number generator using system-supplied value as seed.
var rand = new Random();

// Generate and display 5 random byte (integer) values.
byte[] 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 RandomExample2
    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

Aşağıdaki örnek, bir diziden dize değeri almak için dizin olarak kullandığı rastgele bir tamsayı oluşturur.

Random rnd = new();
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:     {malePetNames[mIndex]}");
Console.WriteLine($"   For a female:   {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

Açıklamalar

Note

Rastgele parola oluşturmaya uygun bir sayı gibi şifreleme açısından güvenli rastgele bir sayı oluşturmak için sınıfındaki RandomNumberGenerator statik yöntemlerden birini kullanın.

Random sınıfı, rastgelelik için belirli istatistiksel gereksinimleri karşılayan bir sayı dizisi üreten bir algoritma olan sahte rastgele sayı oluşturucuyu temsil eder.

Sahte rastgele sayılar, sonlu bir sayı kümesinden eşit olasılıkla seçilir. Seçilen sayılar tamamen rastgele değildir çünkü bunları seçmek için bir matematik algoritması kullanılır, ancak pratik amaçlar için yeterince rastgeledir. sınıfının uygulanması Random Donald E. Knuth'un subtractive rastgele sayı oluşturucu algoritmasının değiştirilmiş bir sürümünü temel alır. Daha fazla bilgi için bkz. D. E. Knuth. Bilgisayar Programlama Sanatı, Birim 2: Yarı Sayısal Algoritmalar. Addison-Wesley, Reading, MA, üçüncü sürüm, 1997.

Rastgele parola oluşturmaya uygun bir sayı gibi şifreleme açısından güvenli rastgele bir sayı oluşturmak için sınıfındaki System.Security.Cryptography.RandomNumberGenerator statik yöntemlerden birini kullanın.

Rastgele sayı üreticisini başlatın

Bir Random sınıfı oluşturucusuna tohum değeri (sahte rastgele sayı oluşturma algoritması için başlangıç değeri) sağlayarak rastgele sayı üreticinin örneğini oluşturursunuz. Tohum değerini açık veya örtük olarak sağlayabilirsiniz:

  • Oluşturucu, sizin sağladığınız açık bir tohum değeri kullanır.
  • Oluşturucu varsayılan Random() çekirdek değerini kullanır. Bu, rastgele sayı oluşturucunun örneğini oluşturmanın en yaygın yoludur.

Varsayılan tohum değeri, iş parçacığı statik, sahte rastgele sayı oluşturucu tarafından oluşturulur.

Ayrı Random nesneler için aynı tohum kullanılırsa, aynı rastgele sayı serisini oluşturur. Bu, rastgele değerleri işleyen bir test paketi oluşturmak veya verilerini rastgele sayılardan türeyen oyunları yeniden oynatmak için yararlı olabilir.

Farklı rastgele sayı dizileri oluşturmak için, tohum değerini zamana bağımlı hale getirerek her yeni örneğiyle Randomfarklı bir seri oluşturabilirsiniz. Parametreli Random(Int32) oluşturucu, geçerli zamandaki tıklama sayısına göre bir Int32 değeri alabilirken, parametresiz Random() oluşturucu tohum değerini oluşturmak için sistem saatini kullanır.

İş parçacığı güvenliği

Tek tek Random nesnelerin örneğini oluşturmak yerine uygulamanızın ihtiyaç duyduğu tüm rastgele sayıları oluşturmak için tek Random bir örnek oluşturmanızı öneririz. Ancak, Random nesneler iş parçacığı güvenli değildir. Uygulamanız birden çok iş parçacığından yöntemleri çağırırsa Random , aynı anda yalnızca bir iş parçacığının rastgele sayı oluşturucuya erişebildiğinden emin olmak için bir eşitleme nesnesi kullanmanız gerekir. Nesneye iş parçacığı açısından güvenli bir şekilde erişildiğinden Random emin değilseniz, rastgele sayılar döndüren yöntemlere yapılan çağrılar 0 döndürür.

Aşağıdaki örnekte tek bir rastgele sayı oluşturucuya iş parçacığı güvenli bir şekilde 11 iş parçacığı tarafından erişildiğinden emin olmak için C# lock Deyimi, F# lock işlevi ve Visual Basic SyncLock deyimi kullanılır. Her iş parçacığı 2 milyon rastgele sayı oluşturur, oluşturulan rastgele sayıları sayar ve bunların toplamını hesaplar ve yürütmeyi tamamladığında tüm iş parçacıklarının toplamlarını güncelleştirir.

using System;
using System.Threading;

public class Example18
{
    [ThreadStatic] static double s_previous;
    [ThreadStatic] static int s_perThreadCtr;
    [ThreadStatic] static double s_perThreadTotal;
    static CancellationTokenSource s_source;
    static CountdownEvent s_countdown;
    static object s_randLock, s_numericLock;
    static Random s_rand;
    double _totalValue = 0.0;
    int _totalCount = 0;

    public Example18()
    {
        s_rand = new Random();
        s_randLock = new object();
        s_numericLock = new object();
        s_countdown = new CountdownEvent(1);
        s_source = new CancellationTokenSource();
    }

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

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

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

        s_countdown.Signal();
        // Make sure all threads have finished.
        s_countdown.Wait();
        s_source.Dispose();

        Console.WriteLine($"\nTotal random numbers generated: {_totalCount:N0}");
        Console.WriteLine($"Total sum of all random numbers: {_totalValue:N2}");
        Console.WriteLine($"Random number mean: {_totalValue / _totalCount:N4}");
    }

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

        try
        {
            s_previous = 0.0;
            s_perThreadCtr = 0;
            s_perThreadTotal = 0.0;

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

                lock (s_randLock)
                {
                    result = s_rand.NextDouble();
                }
                // Check for corruption of Random instance.
                if ((result == s_previous) && result == 0)
                {
                    s_source.Cancel();
                }
                else
                {
                    s_previous = result;
                }
                s_perThreadCtr++;
                s_perThreadTotal += result;
            }

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

            // Update overall totals.
            lock (s_numericLock)
            {
                _totalCount += s_perThreadCtr;
                _totalValue += s_perThreadTotal;
            }
        }
        catch (OperationCanceledException e)
        {
            Console.WriteLine($"Corruption in Thread {Thread.CurrentThread.Name}");
        }
        finally
        {
            s_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 Example15
    <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

Örnek, iş parçacığı güvenliğini aşağıdaki yollarla sağlar:

  • ThreadStaticAttribute özniteliği, oluşturulan rastgele sayıların toplam sayısını ve her iş parçacığı için toplamlarını izleyen iş parçacığı yerel değişkenlerini tanımlamak için kullanılır.
  • Kilit (lock C# dilindeki ifade, lock F# işlevi ve SyncLock Visual Basic'teki ifade), tüm iş parçacıklarında üretilen tüm rastgele sayıların toplam sayısı ve toplamına ait değişkenlere erişimi korur.
  • Semafor (CountdownEvent nesnesi), ana iş parçacığını, diğer tüm iş parçacıkları yürütmelerini tamamlayana kadar engellemek için kullanılır.
  • Örnek, rastgele sayı oluşturma yöntemlerine ardışık iki çağrının 0 döndürüp döndürmediğini belirleyerek rastgele sayı oluşturucunun bozulup bozulmadığını denetler. Bozulma algılanırsa, örnek tüm iş parçacıklarının iptal edilmesi gerektiğinin sinyalini vermek için CancellationTokenSource nesnesini kullanır.
  • Her rastgele sayıyı oluşturmadan önce, her iş parçacığı nesnenin CancellationToken durumunu denetler. İptal istenirse, iş parçacığını iptal etmek için örnek CancellationToken.ThrowIfCancellationRequested yöntemini çağırır.

Aşağıdaki örnek, Task nesneleri yerine bir Thread nesne ve lambda ifadesi kullanması dışında ilk örnekle aynıdır.

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

public class Example19
{
    static object s_randLock, s_numericLock;
    static Random s_rand;
    static CancellationTokenSource s_source;
    double _totalValue = 0.0;
    int _totalCount = 0;

    public Example19()
    {
        s_rand = new Random();
        s_randLock = new object();
        s_numericLock = new object();
        s_source = new CancellationTokenSource();
    }

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

    private async Task Execute()
    {
        List<Task> tasks = [];

        for (int ctr = 0; ctr <= 10; ctr++)
        {
            CancellationToken token = s_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 (s_randLock)
                       {
                           result = s_rand.NextDouble();
                       }
                       // Check for corruption of Random instance.
                       if ((result == previous) && result == 0)
                       {
                           s_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 (s_numericLock)
                   {
                       _totalCount += taskCtr;
                       _totalValue += taskTotal;
                   }
               },
            token));
        }
        try
        {
            await Task.WhenAll(tasks.ToArray());
            Console.WriteLine($"\nTotal random numbers generated: {_totalCount:N0}");
            Console.WriteLine($"Total sum of all random numbers: {_totalValue:N2}");
            Console.WriteLine($"Random number mean: {_totalValue / _totalCount:N4}");
        }
        catch (AggregateException e)
        {
            foreach (Exception inner in e.InnerExceptions)
            {
                if (inner is TaskCanceledException canc)
                    Console.WriteLine("Task #{0} cancelled.", canc.Task.Id);
                else
                    Console.WriteLine("Exception: {0}", inner.GetType().Name);
            }
        }
        finally
        {
            s_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 Example16
    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

Aşağıdaki yollarla ilk örnekten farklıdır:

  • Oluşturulan rastgele sayıların sayısını izlemek için değişkenler ve bunların her görevde toplamları görev için yereldir, bu nedenle özniteliğini kullanmaya ThreadStaticAttribute gerek yoktur.
  • Statik Task.WaitAll yöntem, tüm görevler tamamlanmadan önce ana iş parçacığının tamamlanmadığından emin olmak için kullanılır. Nesneye CountdownEvent gerek yoktur.
  • Görev iptali sonucunda oluşan özel durum, Task.WaitAll yönteminde belirginleşir. Önceki örnekte, her iş parçacığı tarafından işlenir.

Farklı rastgele sayı türleri oluşturma

Rastgele sayı oluşturucu, aşağıdaki rastgele sayı türlerini oluşturmanıza olanak sağlayan yöntemler sağlar:

  • Bir dizi Byte değer. Yöntemin döndürmesini istediğiniz eleman sayısıyla başlatılmış bir dizi geçirerek bayt değerlerinin sayısını belirlersiniz. Aşağıdaki örnek 20 bayt oluşturur.

    Random rnd = new();
    byte[] bytes = new byte[20];
    rnd.NextBytes(bytes);
    for (int ctr = 1; ctr <= bytes.Length; ctr++)
    {
        Console.Write($"{bytes[ctr - 1],3}   ");
        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 Example9
        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
    
  • Tek bir tamsayı. yöntemini çağırarak 0'dan en büyük değere (Int32.MaxValue - 1) bir tamsayı mı, yöntemini çağırarak Next()Next(Int32) 0 ile belirli bir değer arasındaki bir tamsayıyı mı yoksa bir değer aralığındaki bir tamsayıyı Next(Int32, Int32) mı istediğinizi seçebilirsiniz. Parametreli aşırı yüklemelerde belirtilen en yüksek değer özeldir; diğer bir ifadeyle, oluşturulan gerçek maksimum sayı belirtilen değerden bir küçüktür.

    Aşağıdaki örnek, -10 ile 10 arasında rastgele 10 sayı oluşturmak için yöntemini çağırır Next(Int32, Int32) . yönteminin ikinci bağımsız değişkeninin, yöntemi tarafından döndürülen rastgele değer aralığının dışlayıcı üst sınırlarını belirttiğini unutmayın. Başka bir deyişle, yöntemin döndürebileceği en büyük tamsayı bu değerden bir küçüktür.

    Random rnd = new();
    for (int ctr = 0; ctr < 10; ctr++)
    {
        Console.Write($"{rnd.Next(-10, 11),3}   ");
    }
    
    // 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 Example11
        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 yöntemini çağırarak 0,0 ile 1,0 arasında tek bir kayan nokta değeri. Yöntemi tarafından döndürülen rastgele sayının özel üst sınırı 1'dir, dolayısıyla asıl üst sınırı 0,9999999999999978'dir. Aşağıdaki örnek 10 rastgele kayan noktalı sayı oluşturur.

    Random rnd = new();
    for (int ctr = 0; ctr < 10; ctr++)
    {
        Console.Write($"{rnd.NextDouble(),-19:R}   ");
        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 Example10
        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
    

Important

yöntemi, Next(Int32, Int32) döndürülen rastgele sayının aralığını belirtmenize olanak tanır. Bununla birlikte maxValue , döndürülen üst aralığı belirten parametre, kapsayıcı değil, özel bir değerdir. Bu, yöntem çağrısının Next(0, 100) 0 ile 99 arasında bir değer döndürdüğü ve 0 ile 100 arasında olmadığı anlamına gelir.

Rastgele Boole değerleri oluşturma, belirtilen aralıkta Random, Rastgele 64 bit tamsayı oluşturma ve dizi veya koleksiyondan benzersiz bir öğe alma gibi görevler için sınıfını da kullanabilirsiniz.

Kendi algoritmanızı değiştirin

Sınıfından Random devralarak ve rastgele sayı oluşturma algoritmanızı sağlayarak kendi rastgele sayı oluşturucunuzu uygulayabilirsiniz. Kendi algoritmanızı sağlamak için rastgele sayı oluşturma algoritmasını Sample uygulayan yöntemini geçersiz kılmanız gerekir. Next(), Next(Int32, Int32) ve NextBytes yöntemlerini de, geçersiz kıldığınız Sample yöntemini çağırdıklarından emin olmak için geçersiz kılmalısınız. Next(Int32) ve NextDouble yöntemlerini geçersiz kılmanız gerekmez.

Random sınıfından türetilen ve varsayılan sahte rastgele sayı oluşturucusunu değiştiren bir örnek için Sample referans sayfasına bakın.

Aynı rastgele değer dizisini alma

Bazen yazılım testi senaryolarında ve oyun oynarken aynı rastgele sayı dizisini oluşturmak istersiniz. Aynı rastgele sayı dizisiyle test etmek regresyonları algılamanıza ve hata düzeltmelerini onaylamanıza olanak tanır. Oyunlarda aynı rastgele sayı dizisini kullanmak, önceki oyunları yeniden oynamanızı sağlar.

Oluşturucuya aynı çekirdek değerini sağlayarak aynı rastgele sayı dizisini Random(Int32) oluşturabilirsiniz. Çekirdek değeri, sahte rastgele sayı oluşturma algoritması için bir başlangıç değeri sağlar. Aşağıdaki örnek, nesnenin örneğini Random oluştururken rastgele bir tohum değeri olarak 100100 kullanır, 20 rastgele kayan nokta değeri görüntüler ve tohum değerini kalıcı yapar. Ardından tohum değerini geri yükler, yeni bir rastgele sayı oluşturucu başlatır ve aynı 20 rastgele kayan nokta değerini görüntüler. Örneğin, .NET'in farklı sürümlerinde çalıştırılırsa farklı rastgele sayı dizileri oluşturabileceğini unutmayın.

using System;
using System.IO;

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

        PersistSeed(seed);

        DisplayNewRandomNumbers();
    }

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

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

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

        Random rnd = new(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
Imports System.IO

Module Example14
    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

Rastgele sayıların benzersiz dizilerini alma

Sınıfın örneklerine farklı tohum değerleri sağlamak, her rastgele sayı oluşturucunun Random farklı bir değer dizisi oluşturmasına neden olur. Random(Int32) oluşturucusunu çağırarak açıkça, veya Random() oluşturucusunu çağırarak örtük olarak bir çekirdek değeri sağlayabilirsiniz. Çoğu geliştirici, sistem saatini kullanan parametresiz oluşturucuyu çağırır. Aşağıdaki örnek, iki Random örneğin örneğini örneklemek için bu yaklaşımı kullanır. Her örnek 10 rastgele tamsayıdan oluşan bir seri görüntüler.

using System;
using System.Threading;

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

        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 Example17
    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

Belirtilen aralıktaki tamsayıları alma

Rastgele sayı oluşturucusunun döndürmesini istediğiniz sayıların Next(Int32, Int32) hem alt hem de üst sınırlarını belirtmenize olanak tanıyan yöntemini çağırarak belirtilen aralıktaki tamsayıları alabilirsiniz. Üst sınır, kapsayıcı değil, özel bir değerdir. Başka bir ifadeyle, yöntemi tarafından döndürülen değer aralığına dahil değildir. Aşağıdaki örnek, -10 ile 10 arasında rastgele tamsayılar oluşturmak için bu yöntemi kullanır. maxValue bağımsız değişkeninin yöntem çağrısındaki değeri olarak 11'in belirtildiğine ve bunun istenen değerden bir fazla olduğuna dikkat edin.

Random rnd = new();
for (int ctr = 1; ctr <= 15; ctr++)
{
    Console.Write($"{rnd.Next(-10, 11),3}    ");
    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 Example12
    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

Belirtilen sayıda basamak içeren tamsayıları alma

Belirtilen sayıda basamak içeren sayıları almak için yöntemini çağırabilirsiniz Next(Int32, Int32) . Örneğin, dört basamaklı sayıları (1000 ile 9999 arasında olan sayılar) almak için, aşağıdaki örnekte gösterildiği gibi 1000 ve Next(Int32, Int32) 10000 değerine sahip minValue yöntemini çağırırsınızmaxValue.

Random rnd = new();
for (int ctr = 1; ctr <= 50; ctr++)
{
    Console.Write($"{rnd.Next(1000, 10000),3}    ");
    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 Example13
    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

Belirtilen aralıktaki kayan nokta değerlerini alma

yöntemi, NextDouble 0 ile 1'in altında arasında rastgele kayan nokta değerleri döndürür. Ancak, genellikle başka bir aralıkta rastgele değerler oluşturmak istersiniz.

İstenen en düşük ve en yüksek değerler arasındaki aralık 1 ise, yöntemi tarafından NextDouble döndürülen sayıya istenen başlangıç aralığı ile 0 arasındaki farkı ekleyebilirsiniz. Aşağıdaki örnek, -1 ile 0 arasında 10 rastgele sayı oluşturmak için bunu yapar.

Random rnd = new();
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 Example6
    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

Alt sınırı 0 olan ancak üst sınırı 1'den büyük olan (veya alt sınırı -1'den küçük ve üst sınırı 0 olan negatif sayılar söz konusu olduğunda) rastgele kayan nokta sayıları oluşturmak için, rastgele sayıyı sıfır olmayan sınırla çarpın. Aşağıdaki örnek, 0 ile arasında 20 milyon rastgele kayan noktalı sayı oluşturmak için Int64.MaxValuebunu yapar. Ayrıca, yöntem tarafından üretilen rastgele değerlerin dağılımını da gösterir.

const long ONE_TENTH = 922337203685477581;

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

// Generate 20 million integer values between.
for (int ctr = 1; ctr <= 20000000; ctr++)
{
    number = rnd.NextDouble() * long.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 : long.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 Example5
    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 %

Yöntemin tamsayılar için yaptığı gibi iki rastgele değer arasında rastgele kayan Next(Int32, Int32) noktalı sayılar oluşturmak için aşağıdaki formülü kullanın:

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

Aşağıdaki örnek, 10,0 ile 11,0 arasında değişen 1 milyon rastgele sayı oluşturur ve bunların dağılımını görüntüler.

Random rnd = new();
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 Example7
    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 * 0.1
            Console.WriteLine("{0:N1} to {1:N1}: {2,8:N0}  ({3,7:P2})",
                           lowerRange, lowerRange + 0.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 %)

Rastgele Boole değerleri oluşturma

Random sınıfı, değer oluşturan Boolean yöntemler sağlamaz. Ancak, bunu yapmak için kendi sınıfınızı veya yönteminizi tanımlayabilirsiniz. Aşağıdaki örnek, BooleanGeneratortek bir yöntemle NextBoolean, sınıfını tanımlar. sınıfı bir BooleanGeneratorRandom nesneyi özel değişken olarak depolar. NextBoolean yöntemi, Random.Next(Int32, Int32) yöntemini çağırır ve sonucu Convert.ToBoolean(Int32) yöntemine geçirir. Rastgele sayının üst sınırlarını belirtmek için bağımsız değişken olarak 2 kullanıldığını unutmayın. Bu özel bir değer olduğundan, yöntem çağrısı 0 veya 1 döndürür.

using System;

public class Example2
{
    public static void Main()
    {
        // Instantiate the Boolean generator.
        BooleanGenerator boolGen = new();
        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 Example2
    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 %)

Örnek, rastgele Boolean değerler oluşturmak için ayrı bir sınıf oluşturmak yerine tek bir yöntem tanımlamış olabilir. Ancak bu durumda, nesnenin her yöntem çağrısında yeni bir Random örneği oluşturmamak için sınıf seviyesinde bir değişken olarak tanımlanmış olması gerekirdi. Visual Basic'te Random örneği yönteminde statik NextBoolean değişken olarak tanımlanabilir. Aşağıdaki örnek bir uygulama sağlar.

Random rnd = new();

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 Example3
    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 %)

Rastgele 64 bit tamsayılar oluşturma

yönteminin Next aşırı yüklemeleri 32 bit tamsayılar döndürür. Ancak bazı durumlarda 64 bit tamsayılarla çalışmak isteyebilirsiniz. Bunu aşağıdaki gibi yapabilirsiniz:

  1. Çift duyarlıklı kayan nokta değeri almak için NextDouble yöntemini çağırın.

  2. Bu değeri Int64.MaxValue ile çarpın.

Aşağıdaki örnek, 20 milyon rastgele uzun tamsayı oluşturmak ve bunları 10 eşit grupta kategorilere ayırmak için bu tekniği kullanır. Ardından, rastgele sayıların dağılımını 0 ile Int64.MaxValue arasındaki her grup için sayarak değerlendirir. Örnekteki çıktıda gösterildiği gibi, sayılar uzun bir tamsayı aralığı boyunca daha fazla veya daha az eşit şekilde dağıtılır.

const long ONE_TENTH = 922337203685477581;

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

// Generate 20 million long integers.
for (int ctr = 1; ctr <= 20000000; ctr++)
{
    number = (long)(rnd.NextDouble() * long.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 : long.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 Example8
    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 %

Bit işleme kullanan alternatif bir teknik gerçekten rastgele sayılar oluşturmaz. Bu teknik, iki tamsayı oluşturmak üzere Next() çağırır, bunlardan birini 32 bit sola kaydırır ve ikisini birleştirerek OR işlemi uygular. Bu tekniğin iki sınırlaması vardır:

  1. Bit 31, işaret biti olduğundan, sonuçta elde edilen uzun tamsayının bit 31'deki değer her zaman 0'dır. Bu, rastgele bir 0 veya 1 oluşturularak, 31 bit sola kaydırılarak ve orijinal rastgele uzun tamsayıya OR ile uygulanarak giderilebilir.

  2. Daha ciddi olarak, Next() tarafından döndürülen değerin 0 olma olasılığı nedeniyle, 0x0-0x00000000FFFFFFFF aralığında çok az ya da hiç rastgele sayı olmayacaktır.

Belirtilen aralıktaki baytları alma

Next yönteminin aşırı yüklemeleri, rastgele sayı aralığını belirtmenize olanak sağlarken, NextBytes yöntemi buna izin vermez. Aşağıdaki örnek, döndürülen bayt aralığını belirtmenize olanak tanıyan bir NextBytes yöntem uygular. Bu, Random2'den türetilen ve Random yöntemini aşırı yükleyen bir NextBytes sınıfını tanımlar.

using System;

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

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

        // Display the results.
        for (int ctr = 0; ctr < total.Length; ctr++)
        {
            Console.Write($"{ctr,3}: {total[ctr],-3}");
            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 Example4
    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) yöntemi, Next(Int32, Int32) yöntemine yapılan çağrıyı sarar ve bayt dizisinde döndürülmesini istediğimiz en düşük değeri ve en yüksek değerden bir fazla olan değeri (bu durumda, 0 ve 101) belirtir. yöntemi tarafından Next döndürülen tamsayı değerlerinin veri türü aralığında Byte olduğundan emin olduğumuzdan, bunları güvenli bir şekilde (C# ve F# dilinde) dönüştürebilir veya (Visual Basic'te) tamsayılardan baytlara dönüştürebiliriz.

Bir diziden veya koleksiyondan rastgele öğe alma

Rastgele sayılar genellikle dizilerden veya koleksiyonlardan değer almak için dizin görevi görür. Rastgele bir dizin değeri almak için Next(Int32, Int32) metodunu çağırabilir ve bağımsız değişkenlerinden biri olarak dizinin alt sınırını, diğeri olarak ise dizinin üst sınırının bir fazlasını kullanabilirsiniz. Sıfır tabanlı bir dizi için bu, özelliğine Length eşdeğerdir veya yöntemi tarafından Array.GetUpperBound döndürülen değerden büyüktür. Aşağıdaki örnek, şehirlerden oluşan bir diziden Birleşik Devletler'deki bir şehrin adını rastgele alır.

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();
int index = rnd.Next(0, cities.Length);
Console.WriteLine($"Today's city of the day: {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 Example1
    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

Diziden veya koleksiyondan benzersiz bir öğe alma

Rastgele bir sayı oluşturucu her zaman yinelenen değerler döndürebilir. Sayı aralığı küçülttüğünde veya oluşturulan değer sayısı arttıkça, yinelenenlerin olasılığı artar. Rastgele değerlerin benzersiz olması gerekiyorsa, yinelemeleri telafi etmek için daha fazla sayı oluşturulur ve bu da performansın giderek düşmesine neden olur.

Bu senaryoyla başa çıkmak için bir dizi teknik vardır. Yaygın çözümlerden biri, alınacak değerleri içeren bir dizi veya koleksiyon ve rastgele kayan nokta sayıları içeren paralel bir dizi oluşturmaktır. İkinci dizi, ilk dizi oluşturulurken rastgele sayılarla doldurulur ve Array.Sort(Array, Array) paralel dizideki değerler kullanılarak ilk diziyi sıralamak için yöntemi kullanılır.

Örneğin, bir Solitaire oyunu geliştiriyorsanız, her kartın yalnızca bir kez kullanıldığından emin olmak istersiniz. Bir kartı almak için rastgele sayılar oluşturmak ve bu kartın dağıtılıp dağıtılmadığını izlemek yerine, desteyi sıralamak için kullanılabilecek rastgele sayılardan oluşan paralel bir dizi oluşturabilirsiniz. Deste sıralandıktan sonra uygulamanız, destedeki bir sonraki kartın dizinini gösteren bir işaretçi bulundurabilir.

Aşağıdaki örnek bu yaklaşımı gösterir. Card bir oyun kartını temsil eden bir sınıf ve karıştırılmış bir kart destesi işleyen bir Dealer sınıf tanımlar. Sınıf Dealer oluşturucu iki diziyi doldurur: deck sınıf kapsamına sahip olan ve destedeki tüm kartları temsil eden bir dizi ve diziyle aynı sayıda öğeye order sahip olan ve rastgele oluşturulan deck değerlerle doldurulan yerel Double bir dizi. Ardından Array.Sort(Array, Array) yöntemi, deck dizisindeki değerlere göre order dizisini sıralamak için çağrılır.

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}", FaceValue, 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 (object suit in Enum.GetValues(typeof(Suit)))
        {
            foreach (object faceValue in Enum.GetValues(typeof(FaceValue)))
            {
                Card card = new()
                {
                    Suit = (Suit)suit,
                    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 {ctr + 1} cards remaining on the deck.");
                return cardsDealt;
            }
        }
        return cardsDealt;
    }
}

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

    private static void ShowCards(Card[] cards)
    {
        foreach (Card 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 UniqueArrayExample
    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

Devralanlara Notlar

.NET Framework 2.0 ve sonraki sürümlerinde, , ve yöntemlerinin Next()davranışı değişmiştir, böylece bu yöntemler mutlaka yönteminin türetilmiş sınıf uygulamasını Next(Int32, Int32) çağırmaz.NextBytes(Byte[])Sample() Sonuç olarak, bu hedef .NET Framework 2.0 ve sonraki sürümlerden Random türetilen sınıflar da bu üç yöntemi geçersiz kılmalıdır.

Arayanlara Notlar

Sınıfındaki rastgele sayı oluşturucunun Random uygulanması, .NET'in ana sürümlerinde aynı kalacağı garanti değildir. Sonuç olarak, aynı tohumun farklı .NET sürümlerinde aynı sahte rastgele diziyle sonuçlandığını varsaymamalısınız.

Oluşturucular

Name Description
Random()

Varsayılan bir tohum değeri kullanarak sınıfın Random yeni bir örneğini başlatır.

Random(Int32)

Belirtilen tohum değerini kullanarak sınıfının yeni bir örneğini Random başlatır.

Özellikler

Name Description
Shared

Herhangi bir iş parçacığından eşzamanlı olarak kullanılabilecek iş parçacığı güvenli Random bir örnek sağlar.

Yöntemler

Name Description
Equals(Object)

Belirtilen nesnenin geçerli nesneye eşit olup olmadığını belirler.

(Devralındığı yer: Object)
GetHashCode()

Varsayılan karma işlevi işlevi görür.

(Devralındığı yer: Object)
GetHexString(Int32, Boolean)

Rastgele onaltılık karakterlerle dolu bir dize oluşturur.

GetHexString(Span<Char>, Boolean)

Arabelleği rastgele onaltılık karakterlerle doldurur.

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

Sağlanan seçenek kümesinden rastgele seçilen öğelerle doldurulmuş bir dizi oluşturur.

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

Belirtilen bir yayılma alanının öğelerini, sağlanan seçenek kümesinden rastgele seçilen öğelerle doldurur.

GetItems<T>(T[], Int32)

Sağlanan seçenek kümesinden rastgele seçilen öğelerle doldurulmuş bir dizi oluşturur.

GetString(ReadOnlySpan<Char>, Int32)

tarafından choicesrastgele seçilen karakterlerle doldurulmuş bir dize oluşturur.

GetType()

Geçerli örneğin Type alır.

(Devralındığı yer: Object)
MemberwiseClone()

Geçerli Objectbasit bir kopyasını oluşturur.

(Devralındığı yer: Object)
Next()

Negatif olmayan rastgele bir tamsayı döndürür.

Next(Int32, Int32)

Belirtilen aralık içinde rastgele bir tamsayı döndürür.

Next(Int32)

Belirtilen maksimumdan küçük negatif olmayan rastgele bir tamsayı döndürür.

NextBinaryFloat<T>()

Rastgelelik için belirli istatistiksel gereksinimleri karşılayan bir sayı dizisi oluşturan bir algoritma olan sahte-rastgele sayı oluşturucusunun temsilidir.

NextBytes(Byte[])

Belirtilen bayt dizisinin öğelerini rastgele sayılarla doldurur.

NextBytes(Span<Byte>)

Belirtilen bayt aralığının öğelerini rastgele sayılarla doldurur.

NextDouble()

0,0'dan büyük veya buna eşit ve 1,0'dan küçük rastgele bir kayan nokta sayısı döndürür.

NextInt64()

Negatif olmayan rastgele bir tamsayı döndürür.

NextInt64(Int64, Int64)

Belirtilen aralık içinde rastgele bir tamsayı döndürür.

NextInt64(Int64)

Belirtilen maksimumdan küçük negatif olmayan rastgele bir tamsayı döndürür.

NextInteger<T>()

Rastgelelik için belirli istatistiksel gereksinimleri karşılayan bir sayı dizisi oluşturan bir algoritma olan sahte-rastgele sayı oluşturucusunun temsilidir.

NextInteger<T>(T, T)

Rastgelelik için belirli istatistiksel gereksinimleri karşılayan bir sayı dizisi oluşturan bir algoritma olan sahte-rastgele sayı oluşturucusunun temsilidir.

NextInteger<T>(T)

Rastgelelik için belirli istatistiksel gereksinimleri karşılayan bir sayı dizisi oluşturan bir algoritma olan sahte-rastgele sayı oluşturucusunun temsilidir.

NextSingle()

0,0'dan büyük veya buna eşit ve 1,0'dan küçük rastgele bir kayan nokta sayısı döndürür.

Sample()

0,0 ile 1,0 arasında rastgele bir kayan nokta sayısı döndürür.

Shuffle<T>(Span<T>)

Bir yayılma alanının yerinde karıştırma işlemini gerçekleştirir.

Shuffle<T>(T[])

Bir dizinin yerinde karıştırma işlemini gerçekleştirir.

ToString()

Geçerli nesneyi temsil eden bir dize döndürür.

(Devralındığı yer: Object)

Şunlara uygulanır