[問題] C++ 亂數產生

看板C_and_CPP作者 (MeMe)時間11年前 (2014/04/23 20:09), 編輯推噓7(7021)
留言28則, 6人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Dev-C++ 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) No 問題(Question): 設定一半徑為500的圓,隨機產生一點於圓內並算出與圓點的距離 現在有個問題就是,我的x1產生出來的值,沒有辦法像y1這麼的隨機 餵入的資料(Input): No 預期的正確結果(Expected Output): x1:-500~500的值,y1:-500~500的值 錯誤結果(Wrong Output): x1感覺有固定的順序,Ex:-433,-427,-420 程式碼(Code):(請善用置底文網頁, 記得排版) #include<stdio.h> #include<stdlib.h> #include<math.h> #include<time.h> main() { int x1,y1; float r1; srand(time(NULL)); x1=(rand()%1000)-500; y1=(rand()%1000)-500; r1=sqrt(x1*x1+y1*y1); if(r1<=500) { printf("x1 = %d\n",x1); printf("y1 = %d\n",y1); printf("r1 = %lf\n",r1); } else { printf("x1 = %d\n",x1); printf("y1 = %d\n",y1); printf("r1 is error\nr1 is %lf\n",r1); } } 補充說明(Supplement): No -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 163.22.18.74 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1398254992.A.DEA.html

04/23 21:15, , 1F
你測了多少次?
04/23 21:15, 1F

04/23 21:16, , 2F
不夠隨機是多不夠隨機?
04/23 21:16, 2F

04/23 21:17, , 3F
你亂數的取法有些瑕疵但是我相信和你的問題無關
04/23 21:17, 3F

04/23 21:36, , 4F
不夠隨機的意思就是,值的範圍都很接近
04/23 21:36, 4F

04/23 21:39, , 5F
不好意思問,亂數的取法有瑕疵,是哪裡有瑕疵
04/23 21:39, 5F

04/23 21:42, , 6F
你抽了三次就覺得都很接近嗎?
04/23 21:42, 6F

04/23 21:55, , 7F
http://ppt.cc/zcqM 執行5次結果
04/23 21:55, 7F

04/23 22:59, , 8F
治標: 在取值給 x1 前先取幾次亂數丟掉
04/23 22:59, 8F

04/23 22:59, , 9F
治本: 想清楚你的「多取幾次」是否適合用迴圈執行
04/23 22:59, 9F

04/23 23:01, , 10F
這其實是另一種型式的「在過近的時間內 srand(time(NULL))」
04/23 23:01, 10F

04/23 23:06, , 11F
google了一下的確有人提到 rand first call 這問題
04/23 23:06, 11F

04/23 23:59, , 12F
我記得devcpp的srand很爛 把前面的亂數先抽掉再用
04/23 23:59, 12F

04/24 00:01, , 13F
他srand之後第一個rand會和seed成線性關係
04/24 00:01, 13F

04/24 00:02, , 14F
所以srand(time)會變成照秒數跑
04/24 00:02, 14F

04/24 00:02, , 15F
更治本的方式是把devcpp丟掉
04/24 00:02, 15F

04/24 01:16, , 16F
只要是 LCG 都是這樣吧...
04/24 01:16, 16F

04/24 02:12, , 17F
一般的LCG不會糟到第一個數用錶就可以預測...
04/24 02:12, 17F

04/24 10:20, , 18F
再糟也不會比 16807 糟吧...又不是多舊的東西(雖然我沒看過)
04/24 10:20, 18F

04/24 20:08, , 19F
azureblaze:你是說它包的mingw嗎= =?
04/24 20:08, 19F

04/24 20:09, , 20F
不然就用 mt19937 : http://p.tl/OQ1z
04/24 20:09, 20F

04/25 00:22, , 21F
基本上 Dev-C++ 用了 MinGW, 就是用 MS-Windows 的 C-Runtime
04/25 00:22, 21F

04/25 00:24, , 22F
DLLs,其中主要就是 MSVCRT.DLL (Microsoft C runtime library)
04/25 00:24, 22F

04/25 00:24, , 23F
而MSVC的 rand() 實作大概就是
04/25 00:24, 23F

04/25 00:25, , 24F
seed=seed*0x343fd+0x269EC3; return (seed>>0x10)&0x7FFF;
04/25 00:25, 24F

04/25 00:29, , 25F
因為 return 時做了 right-shift, 而 seed 的乘數不夠大,
04/25 00:29, 25F

04/25 00:31, , 26F
所以造成srand()用相近的seed,第一次rand()會得到相近的值.
04/25 00:31, 26F

04/26 18:29, , 27F
w64有搬了一些Runtime,不過就算是那樣,問題點也是在
04/26 18:29, 27F

04/26 18:30, , 28F
MSVCRT,而不是DevCPP這個〝IDE〞上面吧@@
04/26 18:30, 28F
文章代碼(AID): #1JLwsGtg (C_and_CPP)