JS語言里常見的隨機函數示例,實驗結果分佈規律分析

来源:https://www.cnblogs.com/xiongzaiqiren/archive/2023/08/04/js-random.html
-Advertisement-
Play Games

在JavaScript語言里有個 Math.random() 隨機函數,用於生成指定範圍內的隨機數。 #### Math.random()函數 根據官方的定義: **Math.random()** 函數返回一個浮點數, 偽隨機數在範圍[0,1),也就是說,從0(包括0)往上,但是不包括1(排除1), ...


  在JavaScript語言里有個 Math.random() 隨機函數,用於生成指定範圍內的隨機數。

Math.random()函數

  根據官方的定義: Math.random() 函數返回一個浮點數, 偽隨機數在範圍[0,1),也就是說,從0(包括0)往上,但是不包括1(排除1),然後您可以縮放到所需的範圍。實現將初始種子選擇到隨機數生成演算法;它不能被用戶選擇或重置。

也就是說 random() 方法可返回介於 0 ~ 1 之間的一個隨機數。比如:0.93228703630515190.081824481973134850.6718927278167157,每次調用它會返回一個含16位小數的隨機浮點數。

  我們日常代碼過程中實際上是需要生成整數,或是指定區間的隨機數,這就需要對它封裝改造一下了。常見的封裝改造有以下幾種。

隨機整數:floor + random

示例:生成隨機整數,傳入參數是最大值(不包括),即返回值是 [0, max)

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

console.log(getRandomInt(3));
// expected output: 0, 1 or 2

console.log(getRandomInt(1));
// expected output: 0

指定區間的隨機數(一)

示例:這個例子返回了一個在指定值之間的隨機數 [min, max)。這個值不小於 min(有可能等於),並且小於(不等於)max。

function getRandomArbitrary(min, max) {
  return Math.random() * (max - min) + min; 
}

console.log(getRandomArbitrary(1,3));
// expected output: 1.0501238302537486,1.9956248025522734,2.7839421306375227 ……

指定區間的隨機數(二)

示例:這個例子返回了一個在指定值之間的隨機整數 [min, max)。這個值不小於 min (如果 min 不是整數,則不小於 min 的向上取整數),且小於(不等於)max。

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
}

console.log(getRandomInt(1,3));
// expected output: 1 or 2

也許很容易想到用 Math.round() 來實現,但是這會導致你的隨機數處於一個不均勻的分佈,這可能不符合你的需求。

指定區間的隨機數(三)

上一個例子提到的函數 getRandomInt() 結果範圍包含了最小值,但不含最大值。如果你的隨機結果需要同時包含最小值和最大值,怎麼辦呢? getRoundRandom() 函數可以實現得到一個兩數之間的隨機整數,包括兩個數在內。

示例:這個例子返回了一個在指定值之間的隨機整數 [min, max]。這個值不小於 min (如果 min 不是整數,則不小於 min 的向上取整數),且不大於max(如果 max 不是整數,則不小於 max 的向下取整數)。

function getRoundRandom(min, max){
    return Math.round(Math.random()*(max-min))+min;
}

console.log(myRoundRandom(1,3));
// expected output: 1, 2 or 3

  需要註意:Math.round() 函數返回一個數字四捨五入後最接近的整數。它取整的結果分佈不均,大概成正泰分佈。驗證:var num = getRoundRandom(0, 5); 生成5輪,每輪10000個結果分佈如下:

指定區間的隨機數(四)

得到一個兩數之間的隨機整數,包括兩個數在內。如果想概率分佈均勻一點可以使用 Math.trunc()
Math.trunc() 方法會將數字的小數部分去掉,只保留整數部分。Math.trunc() 的執行邏輯很簡單,僅僅是刪除掉數字的小數部分和小數點,不管參數是正數還是負數。傳入該方法的參數會被隱式轉換成數字類型。

示例:這個例子返回了一個在指定值之間的隨機整數 [min, max]。這個值不小於 min,且不大於max。

function getTruncRandom(min, max){
    return Math.trunc(Math.random()*(max-min+1))+min;
}

console.log(getTruncRandom(1,3));
// expected output: 1, 2 or 3

可以簡寫:const getTruncRandom=(min,max)=>Math.trunc(Math.random()*(max-min+1)+min);

驗證:var num = getTruncRandom(0, 5); 生成5輪,每輪10000個結果分佈如下:

指定區間的隨機數(五)

前面例子提到的函數 getRandomInt() 結果範圍包含了最小值,但不含最大值。如果你的隨機結果需要同時包含最小值和最大值,怎麼辦呢? getRandomIntInclusive() 函數可以實現得到一個兩數之間的隨機整數,包括兩個數在內。

示例:這個例子返回了一個在指定值之間的隨機整數 [min, max]。這個值不小於 min (如果 min 不是整數,則不小於 min 的向上取整數),且不大於max(如果 max 不是整數,則不小於 max 的向下取整數)。

function getRandomIntInclusive(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random()*(max-min+1))+min; //含最大值,含最小值 
}

console.log(getRandomIntInclusive(1,3));
// expected output: 1, 2 or 3

驗證:var num = getRandomIntInclusive(0, 5); 生成5輪,每輪10000個結果分佈如下:

總結

  1,實驗三採用round + random方式最終驗證隨機結果分佈不均衡,不予採用;
  2,實驗四、實驗五最終驗證隨機結果分佈接近均衡,均可以採用;
  3,實驗四利用 trunc + random 實現方式簡潔,運算次數更少,推薦採用;


附件代碼:生成5輪,每輪10000個結果分佈

<script>
    // round + random()函數
    function getRoundRandom(min, max){
        return Math.round(Math.random()*(max-min))+min;
        /* 實驗結果
        游戲開始:zero = 0 one =0 two =0 three =0 four =0 five=0
        游戲結束:zero = 1034 one =2011 two =1965 three =2004 four =1978 five=1008
        游戲結束:zero = 978 one =2097 two =1967 three =1947 four =2062 five=949
        游戲結束:zero = 1083 one =2066 two =1933 three =1908 four =1986 five=1024
        游戲結束:zero = 994 one =1974 two =2092 three =1918 four =1967 five=1055
        游戲結束:zero = 1010 one =1979 two =2086 three =1970 four =1944 five=1011
        */
    }
    // trunc + random()函數
    function getTruncRandom(min, max){
        return Math.trunc(Math.random()*(max-min+1))+min;
        /* 實驗結果
        游戲開始:zero = 0 one =0 two =0 three =0 four =0 five=0
        游戲結束:zero = 1752 one =1607 two =1636 three =1631 four =1650 five=1724
        游戲結束:zero = 1667 one =1660 two =1696 three =1654 four =1646 five=1677
        游戲結束:zero = 1708 one =1658 two =1658 three =1724 four =1619 five=1633
        游戲結束:zero = 1688 one =1620 two =1689 three =1664 four =1664 five=1675
        游戲結束:zero = 1737 one =1644 two =1655 three =1656 four =1694 five=1614
        */
    }
    // ceil + floor + random()函數
    function getRandomIntInclusive(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 
    }

    function guess(){
        var zero = one = two = three = four = five = 0; // 記錄每個數出現次數

        console.log('游戲開始:zero = '+zero+' one ='+one+' two ='+two+' three ='+three+' four ='+four+' five='+five);
        for(var i=0; i<10000; i++)
        {
            // 自定義生成隨機數
            // var num = getRoundRandom(0, 5); 
            // var num = getTruncRandom(0, 5); 
            var num = getRandomIntInclusive(0, 5);
            
            // 對結果類型計數
            switch(num){
                case 0: zero++; break;
                case 1: one++; break;
                case 2: two++; break;
                case 3: three++; break;
                case 4: four++; break;
                case 5: five++; break;
                default: console.error('生成數字錯誤 num='+num);
            }
        }

        // 該輪結束輸出結果類型計數
        console.log('游戲結束:zero = '+zero+' one ='+one+' two ='+two+' three ='+three+' four ='+four+' five='+five);
    }

    guess();
</script>

【完】


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.確認nginx是否已安裝SSL模塊 查驗方法:進入sbin目錄,執行以下語句,顯示結果如標記所示則表示安裝成功 ./nginx -V 2.確認系統以安裝SSL工具,開始製作證書 選擇一個存放證書的路徑,執行以下語句即可: (1)生成密鑰,得到文件private.key openssl genpk ...
  • ![](https://img2023.cnblogs.com/blog/3076680/202308/3076680-20230803123612359-1050633424.png) # 1. 問題9 ## 1.1. 只講授一門課程的教授 ## 1.2. sql ```sql select p. ...
  • **原文鏈接:** [使用 RediSearch 在 Redis 中進行全文檢索](https://mp.weixin.qq.com/s/X1qKL0jMaklGw6GLcrkp2g) Redis 大家肯定都不陌生了,作為一種快速、高性能的鍵值存儲資料庫,廣泛應用於緩存、隊列、會話存儲等方面。 然而 ...
  • #### 第3句 今日流失用戶 ##### 需求: 當日流失用戶的定義:昨天登錄的,今天沒登錄的用戶數 有一張用戶登錄日誌表,有欄位 date_stamp(日期時間戳),用戶id(uid)。如果用戶在某天登錄了,該表會有一條記錄。 ``` #今天流失人數:昨天登錄,今天沒登錄的 select a.d ...
  • TopSQL為DWS的監控系統,記錄DWS中各個作業、運算元級別的資源使用數據、耗時數據,包括下盤信息、記憶體、網路、耗時、警告、基礎信息等作業執行的數據。 ...
  • ![file](https://img2023.cnblogs.com/other/2685289/202308/2685289-20230803180034435-79319118.png) ## 導讀 國內某頭部券商是國內排名前三的全國性大型綜合證券公司。作為證券行業領頭羊之一,該券商一直高度重 ...
  • 本文分享自華為雲社區《如何為物聯網設備註入“華為雲+鴻蒙DNA”?看華為雲IoT怎麼答【華為雲IoT +鴻蒙】》,作者: 華為IoT雲服務。 根據市場咨詢機構預測,2025年全球物聯網設備將達到252億個。但各種智能設備大多都有一套自己的系統,而且互相“孤立”,無法交流。鴻蒙的到來,就是要用同一套語 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 發現很多人還只會promise常規用法 在js項目中,promise的使用應該是必不可少的,但我發現在同事和麵試者中,很多中級或以上的前端都還停留在promiseInst.then()、promiseInst.catch()、Promis ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...