2010-04-19 144 views
3

在C++中,如何在-10到10的區間內產生隨機數?C++中從-10到10的隨機數

srand(int(time(0)));//seed 
for(int i = 0; i < size; i++){ 
myArray[i] = 1 + rand() % 20 - 10;//this will give from -9 to 10 
myArray2[i] =rand() % 20 - 10;//and this will -10 to 9 
} 
+1

在C++ 11中,您希望使用''庫。 – bames53 2012-10-12 17:26:56

+0

@ bames53同意我使用'std :: uniform_int_distribution'就像我在我的回答中做的那樣更有意義,尤其是考慮到[rand()Considered Harmful](http://channel9.msdn.com/Events/GoingNative/2013/rand-認爲有害)。 – 2013-09-09 01:54:53

回答

8

你需要一系列的21,而不是20,所以做這樣的事情:

x = rand() % 21 - 10; 
+1

只是爲了增加這個...原因是實際上有21種可能性......數出來。包括0。 – mpen 2010-04-19 07:54:52

+3

請注意,使用樸素模數會偏向較小的數字。如果你需要一致性,那麼你需要拒絕一些數字'rand()'返回。 – Joey 2010-04-19 08:00:03

+5

rand()從0..RAND_MAX生成數字,其中RAND_MAX與庫相關,但必須至少爲32767.如果RAND_MAX%21!= 0,則獲得特定數字的概率更高。在大多數實際應用中,這並不重要,但在某些科學計算中,這可能會嚴重影響計算結果。 – zoli2k 2010-04-19 08:03:58

0

你有一個fencepost錯誤 - 你感興趣的範圍是比你使用的模大一個;而不是嘗試:

myArray2[i] =rand() % 21 - 10;//and this will -10 to +10 
+0

不知道爲什麼這會吸引匿名downvote? – 2013-09-07 18:23:37

0

rand() % 21 - 10

0

如果你想要的數字是在範圍[ - 10,10],那麼你有21個可能的數字。

(rand() % 21) - 10; 
4

可以使用rand() % 21產生[0,20]之間的隨機數,然後從每一個生成的號碼減去10

0

(rand()%21) - 10; ?

或者我在這裏錯過了什麼?

8

使用Boost Random Number Library。內置的隨機數發生器具有非常差的分配質量。此外,boost還爲您提供了許多有用的生成器。

// based on boost random_demo.cpp profane demo 
#include <iostream> 

#include <boost/random/mersenne_twister.hpp> 
#include <boost/random/uniform_int.hpp> 
#include <boost/random/variate_generator.hpp> 

int main() { 
    boost::mt19937 gen(42u); // seed generator 
    boost::uniform_int<> uni_dist(-10, 10); // random int from -10 to 10 inclusive 
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > 
    uni(gen, uni_dist); // callable 

    for(int i = 0; i < 10; i++) 
    std::cout << uni() << ' '; 
} 

輸出:從未來

-3 6 9 -7 5 6 2 2 -7 -1 

注:這是built-in in C++11現在。

+0

+1。它甚至爲您提供了一個從一個範圍內生成一個數字的函數。沒有所有這種做錯的麻煩:-) – Joey 2010-04-19 09:05:30

10

爲了得到均勻分佈,你必須把使用RAND_MAX第一

static_cast<int>(21*static_cast<double>(rand())/(RAND_MAX+1)) - 10 

rand() % 21 - 10; 

更快,往往是在應用中使用,但所得到的分佈並不均勻,。函數rand()生成從0RAND_MAX的數字。如果RAND_MAX%21!=0較低的數字以較高的概率生成。

您也可以考慮使用模方法,但用一些隨機數滴:

int randMax = RAND_MAX - RAND_MAX%21; 

int p=RAND_MAX+1; 
while(p>randMax) 
     p=rand(); 

x=p%21 - 10; 

編輯(由約翰和史蒂夫評論):

RAND_MAX有分裂是來自範圍內的一些數字,這些數字將被更頻繁地選擇,因此正確的處理方式是拒絕將導致目標區間上的不均勻分佈的數字。

使用Boost隨機庫(由Danvil提到),隨機數均勻性的所有問題都被消除了。

+0

使用模數而不是除法是獲得隨機整數的更簡單的方法。 – Danvil 2010-04-19 08:08:15

+5

@Danvil它更快但錯誤。它不會產生均勻分佈的隨機數。 – zoli2k 2010-04-19 08:13:30

+0

@danvil:你覺得「整潔」是什麼意思?使用模數不會返回一個均勻分佈的隨機數,因爲zoli2k和smt在這裏都有解釋。我提出瞭解決downvote的答案。 – 2010-04-19 08:15:06

0

使用這將工作:

int x = (rand() % 21) - 10; 
cout<<x; 
1

你可以使用Knuth的消減隨機數發生器產生在(0,1)數字,「U」,然後使用這個簡單的線性方程得到在[-10,10]的隨機數:

-10*u + (1-u)*10 
3

使用C++ 11的random庫,這是更簡單,更不容易出錯(rand() Considered Harmful presentationslides更多詳情)。下面的示例在間隔[-10,10]中生成數字:

#include <iostream> 
#include <random> 

int main() 
{ 
    std::random_device rd; 

    std::mt19937 e2(rd()); 

    std::uniform_int_distribution<int> dist(-10, 10); 

    for (int n = 0; n < 10; ++n) { 
      std::cout << dist(e2) << ", " ; 
    } 
    std::cout << std::endl ; 
}