English Deutsch Français Italiano Español Português 繁體中文 Bahasa Indonesia Tiếng Việt ภาษาไทย
所有分類

亂數取值,最大亂數值只到32767
但如果數字設在0到85000
亂數的設定要怎寫
才能讓他跑出32767之後的亂數值

2007-03-24 00:23:46 · 4 個解答 · 發問者 小井 1 in 電腦與網際網路 程式設計

4 個解答

你講的沒錯.rand()會回傳一個在0~RAND_MAX(32767)中的亂數(VC++).那如果你要求的亂數是在a~b之間怎麼辦?用一點數學即可.
0 <= rand() <= RAND_MAX
兩邊除以RAND_MAX
0/ RAND_MAX <= rand()/RAND_MAX <= RAND_MAX/ RAND_MAX
0 <= rand()/RAND_MAX <= 1
兩邊乘以b-a (a和b之間的數字)
(b-a)*0 <= (b-a)*rand()/RAND_MAX <= (b-a) * 1
0 <= (b-a)*rand()/RAND_MAX <= b-a
之後兩邊都加a.
0+a <= (b-a)*rand()/RAND_MAX + a<= (b-a) + a
a<= (b-a)*rand()/RAND_MAX + a<= b
這樣(b-a)*rand()/RAND_MAX + a不就會回傳一個在a和b之間的亂數了嗎?自己試試看
懂不懂?不懂請再問

2007-03-24 11:46:35 補充:
Ok,既然被講出破綻了.那我再試一個吧.若用VC 裡的rand()來產生自定範圍的亂數的話.多多少少都會有些誤差.我所謂的誤差就是有些數的出現率比較高.除非你要的範圍裡總共有2^n個數.至於誤差大小就在於你用的方法了.比如說byte所說的.取三次亂數相加.雖然方法非常簡單(可能是最簡單的一種).但是其誤差也很大.比如說0出現的機率是1/35184372088832.因三次亂數都要是0.但是1的機率是3/35184372088832.是0的三倍.而2的機率是6/35184372088832.(byte,就事論事.絕無冒犯之意.若有請原諒).

2007-03-24 11:46:49 補充:
還有一種方法是取2次亂數.取第一次亂數除以4的餘數然後再乘以32768再加上第二次的亂數.這樣會出現0到131071之間的亂數.取出這亂數之後有兩種做法
1. 將取出的亂數除以131071再乘以85000.如此0到85000個數都會出現.只不過還是會出現有些數出現的機率是其它數出現的機率的兩倍.但至少會比取三次的效果好
2. 如果出現的亂數大於85000的話就重取.這樣再0到85000出現的機率都一樣了.

2007-03-24 11:48:18 補充:
為何要如此做? 取第一次亂數除以4的餘數是因為0到32767有32768個數.這32768可以平均分成四組所以每一組都有8192的數.所以每組的機率都一樣.再乘以32768是因為在2的次方數裡最接近85000且比85000大的數是131072.131072可以代表0到131071.換成2進位總共有16個bits.所以第一次亂數是求取131072的前2個bits.第二次亂數是求取131072的後14個bits.這種做法應會平均分配0到131071裡每個數的機率.求出從0到131071裡的變數之後就選上面兩種做法的其中一種就可以啦.

2007-03-24 11:49:40 補充:
也就是說((rand()%4)*0x8000) rand()會給你一個從0到131071裡的變數.
還有一種是寫自己的rand()函式囉
以上乃個人見解.有錯請糾正
懂不懂?不懂請再問

2007-03-24 01:22:01 · answer #1 · answered by 7 · 0 0

最低數┼ int((最高數┼1)*rand()/(RAND_MAX┼1))
以 int 資料型態來說
如果最大值是 32767
範圍是超過
不過修改一下就 OK 了!

最低數┼(long int)((最高數┼1)*rand()/(RAND_MAX┼1))

2007-03-27 13:00:21 · answer #2 · answered by Wow 6 · 0 0

( (rand()<<15) | rand() ) % 85000
應該是最快、平均性尚可的做法。

這個做法可快速算出 2^30 以下的亂數。
並可如法泡製快速做出 2^(15*n)的亂數。

但,它有龍大指出的缺點:0 ~ 2^30-1 間的平均性不佳!
而且,當 n 越大,這問題越嚴重!

2007-03-26 07:02:56 補充:
簡單的解決之道:
找個 2^n >> 85000,如法做出這樣的亂數,再 %。
就是說,不要用剛剛 > 85000 的!

如:想用 2^ 24 = 16777216 去 % 85000,建議用:
Rnd = ( (rand( )&0x38) << 3) | (rand( ) >> 3);
再 Rnd % 85000 之類(看你要快、還是要平均性。)

2007-03-26 07:04:32 補充:
為什麼第二個 rand 要 >> 3?
rand 高 bits 比 低 bits 平均性好!!
既然用了二個 rand 得到 15*2 = 30 個 bits 而只要 24 個 bits?
我們為何不捨去二組各別的低 3 個 bits?

這也就是為何第一個 rand 要 &0x38 的原因。

不過,第一個 rand 要 << 9 ,不是 << 3,寫錯了!!

2007-03-26 07:09:13 補充:
Rnd % 85000 是取低 bits 的做法。
這也是大數人的做法。

要均勻性,不要這樣做!!

(int) (Rnd * 85000.) / RANDOM_MAX;
當然,這裡的 RANDOM_MAX 不是內定的 RAND_MAX = 32767。
它是 2^24-1

(有個功課留給你自己做:這樣做最大值是 85000 還是 84999?
 萬一是 84999,你會改成 85000 吧!)

這種要平均性不要速度的做法,其實我也只用過一次。
所以,不記得上面留給的的功課是啥了。

2007-03-26 07:12:16 補充:
喔,漏寫了 第二個意見中,n 很大時,怎麼解決:
再用一個亂數,決定這次的 n 是多少!

不過,既然 n 很大,最有平均性的做法,還是龍大寫的:
自己寫個亂數程式。

2007-09-12 00:14:54 補充:
寫了一篇接近 rand( ) 大全的東東,歡迎有興趣者逛逛。^_^
http://www.phpbbserver.com/graphicsparalle/viewtopic.php?p=201

2007-03-26 02:55:01 · answer #3 · answered by ? 7 · 0 0

龍 大師的做法
是可以產生 0 ~ 85000 之間的 32767 個亂數 (以本題言)
卻不能產生 0 ~ 85000 之間的所有亂數

我可以解
但是 本於個人的百日宣言
我不能在知識網上公開解題
如果你有需要
請直接來函詢問 解題專用信箱
(如何來函? 這是你的習題, 一個簡單的作業, 讓你動動腦)

2007-03-24 02:14:13 · answer #4 · answered by JJ 7 · 0 0

fedest.com, questions and answers