2009-06-30 49 views
99

Có thể tạo ra một số ngẫu nhiên giữa 2 đôi?Số ngẫu nhiên giữa 2 số đôi

Ví dụ:

public double GetRandomeNumber(double minimum, double maximum) 
{ 
    return Random.NextDouble(minimum, maximum) 
} 

Sau đó, tôi gọi nó là như sau:

double result = GetRandomNumber(1.23, 5.34); 

Bất kỳ suy nghĩ sẽ được đánh giá.

Trả lời

241

Có.

Random.NextDouble trả về gấp đôi từ 0 đến 1. Sau đó nhân số đó với phạm vi bạn cần phải đi vào (chênh lệch giữa cực đại và cực đại) và sau đó thêm số đó vào cơ sở (tối thiểu).

public double GetRandomNumber(double minimum, double maximum) 
{ 
    Random random = new Random(); 
    return random.NextDouble() * (maximum - minimum) + minimum; 
} 

Mã thực phải ngẫu nhiên là thành viên tĩnh. Điều này sẽ tiết kiệm chi phí cho việc tạo trình tạo số ngẫu nhiên và sẽ cho phép bạn gọi hàm GetRandomNumber rất thường xuyên. Vì chúng tôi đang khởi tạo một RNG mới với mọi cuộc gọi, nếu bạn gọi đủ nhanh để thời gian hệ thống không thay đổi giữa các cuộc gọi, RNG sẽ được tạo cùng với dấu thời gian chính xác và tạo cùng một số các số ngẫu nhiên.

+24

Chỉ cần xem ra nếu bạn gọi GetRandomNumber() trong một vòng lặp vì nó sẽ tạo ra các giá trị tương tự hơn và hơn –

+0

@ John - Điểm tốt, tôi đã thêm này để trả lời của tôi. – Michael

+0

hoàn hảo! đây là những gì tôi đang tìm kiếm. Cảm ơn bạn rất nhiều – CodeLikeBeaker

6

Cách tiếp cận đơn giản nhất sẽ tạo ra một số ngẫu nhiên giữa 0 và sự khác biệt của hai số. Sau đó, thêm nhỏ hơn của hai số vào kết quả.

3

Bạn có thể sử dụng mã như thế này:

public double getRandomNumber(double minimum, double maximum) { 
    return minimum + randomizer.nextDouble() * (maximum - minimum); 
} 
+2

Whow, một phép thuật 'randomizer var' đã apeared !! – Lucas

2

Bạn có thể làm điều này:

public class RandomNumbers : Random 
{ 
    public RandomNumbers(int seed) : base(seed) { } 

    public double NextDouble(double minimum, double maximum) 
    { 
     return base.NextDouble() * (maximum - minimum) + minimum; 
    } 
} 
0

Về tạo ra các số ngẫu nhiên tương tự nếu bạn gọi nó trong một vòng lặp một giải pháp tiện lợi là để khai báo đối tượng Random() mới bên ngoài vòng lặp dưới dạng biến toàn cục.

Lưu ý rằng bạn phải khai báo cá thể của bạn của lớp Ngẫu nhiên bên ngoài hàm GetRandomInt nếu bạn định chạy nó trong vòng lặp.

"Tại sao điều này?" Bạn hỏi.

Vâng, lớp Ngẫu nhiên thực sự tạo ra các số ngẫu nhiên giả, với "hạt giống" cho trình ngẫu nhiên là thời gian hệ thống. Nếu vòng lặp của bạn đủ nhanh, thời gian đồng hồ hệ thống sẽ không xuất hiện khác với trình ngẫu nhiên và mỗi thể hiện mới của lớp Ngẫu nhiên sẽ bắt đầu với cùng một hạt giống và cung cấp cho bạn cùng một số ngẫu nhiên giả.

Nguồn ở đây: http://www.whypad.com/posts/csharp-get-a-random-number-between-x-and-y/412/

+0

Điều này phù hợp hơn với tư cách là nhận xét vì nó thậm chí không cố trả lời câu hỏi thực tế của OP. –

28

Johnny5 đề xuất tạo phương pháp mở rộng. Dưới đây là một hoàn chỉnh hơn mã ví dụ cho thấy làm thế nào bạn có thể làm điều này:

public static class RandomExtensions 
{ 
    public static double NextDouble(
     this Random random, 
     double minValue, 
     double maxValue) 
    { 
     return random.NextDouble() * (maxValue - minValue) + minValue; 
    } 
} 

Bây giờ bạn có thể gọi nó như thể nó là một phương thức trên lớp Random:

Random random = new Random(); 
double value = random.NextDouble(1.23, 5.34); 

Lưu ý rằng bạn không nên tạo nhiều của các đối tượng mới Random trong một vòng lặp vì điều này sẽ giúp bạn có khả năng nhận được cùng một giá trị nhiều lần trong một hàng. Nếu bạn cần nhiều số ngẫu nhiên thì hãy tạo một phiên bản Random và sử dụng lại nó.

1

Điều gì xảy ra nếu một trong các giá trị là số âm? Sẽ không phải là một ý tưởng tốt hơn là:

double NextDouble(double min, double max) 
{ 
     if (min >= max) 
      throw new ArgumentOutOfRangeException();  
     return random.NextDouble() * (Math.Abs(max-min)) + min; 
} 
+0

Cảm ơn các ý tưởng bổ sung. Rất hữu ích cho một câu hỏi cũ :) – CodeLikeBeaker

+5

Tôi nghĩ rằng 'Math.Abs ​​()' là dư thừa. Vì bạn đã đảm bảo rằng 'min> = max', thì' max - min' phải là một số không âm. –

0
Random random = new Random(); 

double NextDouble(double minimum, double maximum) 
{ 

    return random.NextDouble()*random.Next(minimum,maximum); 

} 
4

Coi chừng: nếu bạn đang tạo ra random bên trong một vòng lặp như ví dụ for(int i = 0; i < 10; i++), không đặt việc kê khai new Random() bên trong vòng lặp.

Từ MSDN:

Các ngẫu nhiên bắt đầu hệ số từ một giá trị giống. Nếu cùng một hạt giống được sử dụng nhiều lần, cùng một chuỗi số được tạo. Một cách để tạo ra các chuỗi khác nhau là làm cho giá trị hạt giống phụ thuộc vào thời gian, do đó tạo ra một chuỗi khác nhau với mỗi trường hợp ngẫu nhiên mới. Theo mặc định, các nhà xây dựng parameterless của lớp ngẫu nhiên sử dụng đồng hồ hệ thống để tạo ra giá trị hạt giống của nó ...

Vì vậy, dựa trên thực tế này, làm điều gì đó như:

var random = new Random(); 

for(int d = 0; d < 7; d++) 
{ 
    // Actual BOE 
    boes.Add(new LogBOEViewModel() 
    { 
     LogDate = criteriaDate, 
     BOEActual = GetRandomDouble(random, 100, 1000), 
     BOEForecast = GetRandomDouble(random, 100, 1000) 
    }); 
} 

double GetRandomDouble(Random random, double min, double max) 
{ 
    return min + (random.NextDouble() * (max - min)); 
} 

Làm cách này bạn có đảm bảo bạn sẽ nhận được các giá trị kép khác nhau.

0

Nếu bạn cần số ngẫu nhiên trong phạm vi [double.MinValue; double.MaxValue]

// Because of: 
double.MaxValue - double.MinValue == double.PositiveInfinity 

// This will be equals to NaN or PositiveInfinity 
random.NextDouble() * (double.MaxValue - double.MinValue) 

Sử dụng thay vì:

public static class RandomExtensions 
{ 
    public static double NextDoubleInMinMaxRange(this Random random) 
    { 
     var bytes = new byte[sizeof(double)]; 
     var value = default(double); 
     while (true) 
     { 
      random.NextBytes(bytes); 
      value = BitConverter.ToDouble(bytes, 0); 
      if (!double.IsNaN(value) && !double.IsInfinity(value)) 
       return value; 
     } 
    } 
} 
+1

Điểm tốt, nhưng đề xuất này dẫn đến phân phối sai lệch như trong ví dụ thứ hai ở đây https://stackoverflow.com/a/3365388/3922292 –

Các vấn đề liên quan