Iya.
Random.NextDouble mengembalikan dua kali lipat antara 0 dan 1. Anda kemudian kalikan dengan rentang yang Anda butuhkan (perbedaan antara maksimum dan minimum) dan kemudian tambahkan ke basis (minimum).
public double GetRandomNumber(double minimum, double maximum)
{
Random random = new Random();
return random.NextDouble() * (maximum - minimum) + minimum;
}
Kode nyata seharusnya acak menjadi anggota statis. Ini akan menghemat biaya pembuatan generator angka acak, dan akan memungkinkan Anda untuk memanggil GetRandomNumber sangat sering. Karena kami menginisialisasi RNG baru dengan setiap panggilan, jika Anda menelepon cukup cepat sehingga waktu sistem tidak berubah di antara panggilan, RNG akan diunggulkan dengan stempel waktu yang sama persis, dan menghasilkan aliran angka acak yang sama.
public double GetRandomNumber(this Random random, double minimum, double maximum) {...}
Johnny5 menyarankan untuk membuat metode ekstensi. Berikut contoh kode yang lebih lengkap yang menunjukkan bagaimana Anda bisa melakukan ini:
Sekarang Anda dapat menyebutnya seolah-olah itu adalah metode di
Random
kelas:Perhatikan bahwa Anda tidak boleh membuat banyak
Random
objek baru dalam satu lingkaran karena ini akan memungkinkan Anda mendapatkan nilai yang sama beberapa kali berturut-turut. Jika Anda membutuhkan banyak angka acak, buat satu contohRandom
dan gunakan kembali.sumber
Hati-hati: jika Anda membuat
random
loop dalam seperti misalnyafor(int i = 0; i < 10; i++)
, jangan meletakkannew Random()
deklarasi di dalam loop.Dari MSDN :
Jadi berdasarkan fakta ini, lakukan sesuatu seperti:
Dengan melakukan ini, Anda memiliki jaminan Anda akan mendapatkan nilai ganda yang berbeda.
sumber
Pendekatan paling sederhana hanya akan menghasilkan angka acak antara 0 dan perbedaan dari dua angka. Kemudian tambahkan yang lebih kecil dari dua angka ke hasilnya.
sumber
Anda dapat menggunakan kode seperti ini:
sumber
Anda bisa melakukan ini:
sumber
Saya agak terlambat ke pesta tetapi saya perlu menerapkan solusi umum dan ternyata tidak ada solusi yang dapat memenuhi kebutuhan saya.
Solusi yang diterima baik untuk rentang kecil; Namun,
maximum - minimum
bisa menjadi tak terbatas untuk rentang besar. Jadi versi yang diperbaiki dapat berupa versi ini:Ini menghasilkan angka acak dengan baik bahkan antara
double.MinValue
dandouble.MaxValue
. Tapi ini memperkenalkan "masalah" lain, yang disajikan dengan baik dalam posting ini : jika kita menggunakan rentang besar seperti itu nilainya mungkin terlihat terlalu "tidak wajar". Misalnya, setelah menghasilkan 10.000double.MaxValue
rangkap acak antara 0 dan semua nilai berada di antara 2.9579E + 304 dan 1.7976E + 308.Jadi saya juga membuat versi lain, yang menghasilkan angka pada skala logaritmik:
Beberapa tes:
Berikut adalah hasil yang diurutkan menghasilkan 10.000 angka ganda acak antara 0 dan
Double.MaxValue
dengan kedua strategi. Hasilnya ditampilkan dengan menggunakan skala logaritmik:Meskipun nilai acak linier tampaknya salah pada pandangan pertama, statistik menunjukkan bahwa tidak ada yang lebih baik daripada yang lain: bahkan strategi linier memiliki distribusi yang merata dan perbedaan rata-rata antara nilai hampir sama dengan kedua strategi .
Bermain dengan rentang yang berbeda menunjukkan kepada saya bahwa strategi linier menjadi "waras" dengan rentang antara 0 dan
ushort.MaxValue
dengan nilai minimum "masuk akal" dari 10.78294704 (untukulong
rentang nilai minimum adalah 3.03518E + 15int
;: 353341). Ini adalah hasil yang sama dari kedua strategi yang ditampilkan dengan skala yang berbeda:Edit:
Baru-baru ini saya membuat perpustakaan saya open source, merasa bebas untuk melihat
RandomExtensions.NextDouble
metode dengan validasi lengkap.sumber
Bagaimana jika salah satu nilai negatif? Bukankah ide yang lebih baik:
sumber
Math.Abs()
itu berlebihan. Karena Anda memastikan itumin >= max
, makamax - min
harus menjadi nomor yang tidak negatif.Jika Anda memerlukan nomor acak dalam kisaran [
double.MinValue
;double.MaxValue
]Gunakan sebaliknya:
sumber
Tentang membuat nomor acak yang sama jika Anda memanggilnya dalam sebuah loop, solusi yang bagus adalah dengan mendeklarasikan objek Random () baru di luar loop sebagai variabel global.
Perhatikan bahwa Anda harus mendeklarasikan instance Anda dari kelas acak di luar fungsi GetRandomInt jika Anda akan menjalankan ini dalam satu lingkaran.
"Kenapa ini?" Anda bertanya.
Nah, kelas Random sebenarnya menghasilkan angka acak semu, dengan "seed" untuk randomizer menjadi waktu sistem. Jika loop Anda cukup cepat, waktu jam sistem tidak akan tampak berbeda dengan randomizer dan setiap instance baru dari kelas Random akan memulai dengan seed yang sama dan memberi Anda nomor acak semu yang sama.
Sumber ada di sini: http://www.whypad.com/posts/csharp-get-a-random-number-between-x-and-y/412/
sumber
Gunakan Acak statis atau angka-angka cenderung berulang dalam loop ketat / cepat karena jam sistem seeding mereka.
Lihat juga: https://docs.microsoft.com/en-us/dotnet/api/system.random?view=netframework-4.8
sumber
sumber