摘要:另外,這幾篇幾個(gè)不錯(cuò)的隨機(jī)生成隨機(jī)數(shù)采用對(duì)獲取的浮點(diǎn)數(shù)進(jìn)行取整操作,也是同樣的問(wèn)題,能取到左端點(diǎn),卻無(wú)法取到右端點(diǎn)。
最近在琢磨內(nèi)置對(duì)象Math的時(shí)候,參考了很多網(wǎng)上資料,不過(guò)我在Google中搜索js 隨機(jī)整數(shù),出來(lái)很多博客文章,很遺憾,在我看來(lái)排名靠前的這些文章都是錯(cuò)誤的。接下來(lái)我將會(huì)論證我這一觀點(diǎn),同時(shí)把我所理解的Math.random()方法跟你分享。
在這篇文章中,作者給出了如下方法,根據(jù)他的文章描述,這個(gè)算法能產(chǎn)生start到end之間的隨機(jī)整數(shù)。
javascriptfunction rnd(start, end){ return Math.floor(Math.random() * (end - start) + start); }一個(gè)需要確認(rèn)的問(wèn)題
在說(shuō)我的觀點(diǎn)之前,我希望先明確一件事情,設(shè)想別人跟你提了一個(gè)需求:
需要一個(gè)生成a到b之間隨機(jī)整數(shù)的方法。
這時(shí)候我覺(jué)得你至少需要跟對(duì)方確認(rèn)一個(gè)問(wèn)題:包不包括兩個(gè)端點(diǎn),即a和b ?
(其實(shí)還有一些問(wèn)題需要考慮的,比如傳入的a和b如果不是數(shù)字類型?如果是小數(shù)?如果是負(fù)數(shù)?如果a比b大?為了專注本文要討論的內(nèi)容,我們假定傳入的a和b都是合法的正整數(shù),且a<b。)
如果對(duì)方給你確認(rèn)了,那是墜吼的;但是如果對(duì)方?jīng)]有確認(rèn),如何理解這一需求?我認(rèn)為在對(duì)上述需求沒(méi)有更多說(shuō)明的情況下,以下兩個(gè)是靠譜的理解:
既要包括端點(diǎn)a,也要包括端點(diǎn)b。
既不包括端點(diǎn)a,也不包括端點(diǎn)b。
所以,如果你實(shí)現(xiàn)的方法能獲取的只包含其中一個(gè)端點(diǎn),我覺(jué)得這種實(shí)現(xiàn)是不太理想的,你再琢磨這句話:a到b之間的隨機(jī)整數(shù)。
如果你也認(rèn)同我的這段論述,接下來(lái)回到開(kāi)頭那個(gè)方法,看他能不能實(shí)現(xiàn)獲取從start到end之間的隨機(jī)整數(shù);方法主體就一個(gè)運(yùn)算表達(dá)式:
javascriptreturn Math.floor(Math.random() * (end - start) + start);
逐步分析:
javascriptMath.random(); //[0,1) Math.random()*(end-start); //[0,end-start); Math.random()*(end-start)+start; //[start,end); Math.floor(Math.random()*(end-start)+start); //{ x | x>=start,xMath.ceil(Math.random()*3);//得到1-3的整數(shù) 第一行,Math.random()方法返回的是0到1之間的浮點(diǎn)數(shù),注意,__包括0,不包括1!__ECMA語(yǔ)言標(biāo)準(zhǔn)里明確規(guī)定了:
Returns a Number value with positive sign, greater than or equal to 0 but less than 1
所以,這篇博客,和這篇博客是不正確的;由于這兩篇占據(jù)結(jié)果第一頁(yè)的博文比較古老,我甚至在想是不是ECMA標(biāo)準(zhǔn)一開(kāi)始不是這樣子的,然后查了一下,ECMA標(biāo)準(zhǔn)從第一個(gè)版本對(duì)random方法的規(guī)定就是現(xiàn)在這個(gè)樣子。
第二行,Math.random()*(end-start);則返回0到end-start之間的浮點(diǎn)數(shù),包含0,不包含end-start。
第三行, Math.random()*(end-start)+start;返回start到end之間的浮點(diǎn)數(shù),包含start,不包含end。
第四行,Math.floor(Math.random()*(end-start)+start);。這是最關(guān)鍵的一行,對(duì)上一行產(chǎn)生的浮點(diǎn)數(shù)進(jìn)行向下取整,既然是向下取整,結(jié)果可能取到start,卻永遠(yuǎn)取不到end。
根據(jù)前述理解,這樣的實(shí)現(xiàn)我認(rèn)為是不合要求的。所以,這篇文章也是不正確的。
另外,這幾篇幾個(gè)不錯(cuò)的JavaScript隨機(jī)...、js生成隨機(jī)數(shù)采用parseInt對(duì)獲取的浮點(diǎn)數(shù)進(jìn)行取整操作,也是同樣的問(wèn)題,能取到左端點(diǎn),卻無(wú)法取到右端點(diǎn)。parseInt操作浮點(diǎn)數(shù)的效果相當(dāng)于Math.floor()。勘誤:之前寫(xiě)的上面這句話“parseInt操作浮點(diǎn)數(shù)的效果相當(dāng)于Math.floor()”,我在看了這篇文章之后發(fā)現(xiàn)這句話是不對(duì)的,抱歉。但我的結(jié)論是不變的:Math.random()的結(jié)果范圍包括0,因此parseInt(Math.random())也可能取到0
而這一篇JavaScript random方法得到隨機(jī)整數(shù),采用的是Math.ceil()方法進(jìn)行向上取整,
javascript
這樣確實(shí)既能取到右端點(diǎn),也能取到左端點(diǎn),但是作者的左端點(diǎn)標(biāo)錯(cuò)了,這個(gè)是有可能能取到0的,盡管取到0的概率是無(wú)限趨近于0;
這樣引伸出另一個(gè)問(wèn)題:取得的隨機(jī)整數(shù)范圍里,各整數(shù)出現(xiàn)的概率是否一致?
獲取概率問(wèn)題 一個(gè)概率不均等的方法在之前有位老師給出的獲取隨機(jī)數(shù)方法是下面這樣(要求了必須包括端點(diǎn));
javascriptfunction getRandom(n,m){ //省略特殊情形下的處理過(guò)程,比如n>m,或者n、m之一無(wú)法轉(zhuǎn)化為有效數(shù)字; return Math.round(Math.random()*(m-n)+n); }
一個(gè)獲取隨機(jī)整數(shù)的方法,如果不格外的聲明,我覺(jué)得有一個(gè)默認(rèn)的條件應(yīng)該是:
生成每個(gè)整數(shù)的概率應(yīng)當(dāng)是均等的;
根據(jù)第一部分的分析,這個(gè)方法能獲取的浮點(diǎn)數(shù)的范圍是n到m之間,包括n,不包括m;而這個(gè)方法中取整是采用Math.round()四舍五入;這樣的話:
當(dāng)取出的結(jié)果x∈[n,n+0.5)時(shí),會(huì)四舍五入為n;區(qū)間范圍為0.5,概率為0.5/(m-n)*100%;
當(dāng)取出的結(jié)果x∈[n+0.5,n+1.5)時(shí),會(huì)四舍五入為n+1;區(qū)間范圍為1,概率為1/(m-n)*100%;
當(dāng)取出的結(jié)果x∈[n+1.5,n+2.5)時(shí),會(huì)四舍五入為n+2;區(qū)間范圍為1,概率為1/(m-n)*100%;
......
當(dāng)取出的結(jié)果x∈[m-0.5,m)時(shí),會(huì)四舍五入為m;區(qū)間范圍為0.5,概率為0.5/(m-n)*100%;
通過(guò)以上分析,該算法確實(shí)可以達(dá)到目標(biāo),取到n到m之間的隨機(jī)整數(shù),但是并不是每個(gè)整數(shù)出現(xiàn)的概率都是相等的,具體來(lái)說(shuō),取得兩邊端點(diǎn)的整數(shù)概率是其他數(shù)字的一半。所以,我認(rèn)為這也是不夠完美的。
這樣的話,在寫(xiě)一個(gè)獲得概率均等的隨機(jī)整數(shù)方法的時(shí)候,相信你知道應(yīng)該注意些什么問(wèn)題了吧。
總結(jié)總結(jié)一下,當(dāng)我們?cè)讷@取隨機(jī)整數(shù)的時(shí)候,有兩個(gè)問(wèn)題需要特別注意:
一定要仔細(xì)檢查兩邊端點(diǎn)是否是否能取到?是否與需求一致?
獲取到的每個(gè)整數(shù)的概率是否均等?
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85809.html
摘要:目錄導(dǎo)語(yǔ)對(duì)象對(duì)象對(duì)象方法的應(yīng)用日歷插件小結(jié)導(dǎo)語(yǔ)這是標(biāo)準(zhǔn)庫(kù)系列的第二篇文章,主要討論一下對(duì)象和對(duì)象,對(duì)象在平時(shí)處理一些數(shù)學(xué)操作時(shí)能起到事半功倍的作用,目前小羊接觸到的對(duì)象的使用場(chǎng)景是動(dòng)畫(huà)制作對(duì)象作為關(guān)于時(shí)間的接口,能夠?qū)⑵鋺?yīng)用于制作和時(shí)間相關(guān) 目錄 導(dǎo)語(yǔ) 1. Math對(duì)象 2. Date對(duì)象 3. Date對(duì)象方法的應(yīng)用——日歷插件; 4. 小結(jié) 導(dǎo)語(yǔ) 這是《JavaScript標(biāo)準(zhǔn)...
摘要:字符串與數(shù)字間的轉(zhuǎn)換結(jié)果結(jié)果結(jié)果結(jié)果注意會(huì)把一個(gè)類似于的字符串強(qiáng)制轉(zhuǎn)換成判斷是否為有效的數(shù)字某些方法如會(huì)返回一個(gè)特殊的值請(qǐng)注意第點(diǎn)中的注意此方法不完全適合判斷一個(gè)字符串是否是數(shù)字型小數(shù)轉(zhuǎn)整數(shù)結(jié)果四舍五入結(jié)果返回大于的最小整數(shù)結(jié)果返回小于的最 1.字符串與數(shù)字間的轉(zhuǎn)換 var i = 1; var str = i.toString(); //結(jié)果: 1 var str...
摘要:看完部分的源碼,首先迫不及待想跟大家分享的正是本文主題數(shù)組亂序。這是一道經(jīng)典的前端面試題,給你一個(gè)數(shù)組,將其打亂,返回新的數(shù)組,即為數(shù)組亂序,也稱為洗牌問(wèn)題。關(guān)于數(shù)組亂序,正確的解法應(yīng)該是,復(fù)雜度。 前言 終于可以開(kāi)始 Collection Functions 部分了。 可能有的童鞋是第一次看樓主的系列文章,這里再做下簡(jiǎn)單的介紹。樓主在閱讀 underscore.js 源碼的時(shí)候,學(xué)到...
摘要:安全問(wèn)題的分類按照所發(fā)生的區(qū)域分類后端安全問(wèn)題所有發(fā)生在后端服務(wù)器應(yīng)用服務(wù)當(dāng)中的安全問(wèn)題前端安全問(wèn)題所有發(fā)生在瀏覽器單頁(yè)面應(yīng)用頁(yè)面當(dāng)中的安全問(wèn)題按照?qǐng)F(tuán)隊(duì)中哪個(gè)角色最適合來(lái)修復(fù)安全問(wèn)題分類后端安全問(wèn)題針對(duì)這個(gè)安全問(wèn)題,后端最適合來(lái)修復(fù)前端安全 安全問(wèn)題的分類 按照所發(fā)生的區(qū)域分類 后端安全問(wèn)題:所有發(fā)生在后端服務(wù)器、應(yīng)用、服務(wù)當(dāng)中的安全問(wèn)題 前端安全問(wèn)題:所有發(fā)生在瀏覽器、單頁(yè)面應(yīng)用、...
摘要:安全問(wèn)題的分類按照所發(fā)生的區(qū)域分類后端安全問(wèn)題所有發(fā)生在后端服務(wù)器應(yīng)用服務(wù)當(dāng)中的安全問(wèn)題前端安全問(wèn)題所有發(fā)生在瀏覽器單頁(yè)面應(yīng)用頁(yè)面當(dāng)中的安全問(wèn)題按照?qǐng)F(tuán)隊(duì)中哪個(gè)角色最適合來(lái)修復(fù)安全問(wèn)題分類后端安全問(wèn)題針對(duì)這個(gè)安全問(wèn)題,后端最適合來(lái)修復(fù)前端安全 安全問(wèn)題的分類 按照所發(fā)生的區(qū)域分類 后端安全問(wèn)題:所有發(fā)生在后端服務(wù)器、應(yīng)用、服務(wù)當(dāng)中的安全問(wèn)題 前端安全問(wèn)題:所有發(fā)生在瀏覽器、單頁(yè)面應(yīng)用、...
閱讀 799·2021-11-12 10:36
閱讀 3390·2021-09-08 10:44
閱讀 2749·2019-08-30 11:08
閱讀 1408·2019-08-29 16:12
閱讀 2678·2019-08-29 12:24
閱讀 902·2019-08-26 10:14
閱讀 688·2019-08-23 18:32
閱讀 1179·2019-08-23 17:52