Math.random().toString(radix).substr(2) 的長度問題

年前寫了一個程式,很懶惰只在 webkit 上面測試沒在 Firefox 上面測,
結果 demo 的時候就炸開了 orz  ...

最後發現有問題的程式碼是這個:
var randomString = Math.random().toString(16).substr(2); // substr(2) 是把前面的
"0." 拿掉

在 Webkit,randomString 的長度會在 7 和 8 之間跳,
Firefox 則是 13 或是 14 .......

後來是寫了下列的程式碼讓 randomString 的長度固定在 16:

var randomString = (function () {
        var num = '';
        while (num.length < 16) {
            num += Math.random().toString(16).substr(2);
        }
        return num.substr(0,16);
    })();

但是還是想要調查為什麼兩個瀏覽器有這麼大的差異。
當時我和同事的結論是,
雖說 ECMAScript [1] 有規定 Number 型別的數字是  64-bit format IEEE 754 value,0~1 之間有
2^64 個值 [2],
但是 webkit 的假亂數產生器不會用到所有的位數,導致 toString(16) 之後的長度跟 Firefox 不一樣。
只是我自己也沒小心,以為 random() 的小數點長度是固定的。

不過呢,後來玩了一下 toString(radix) [3] 的 radix (進位),
發現「Webkit 產生的位數長度一定比較短」這件事情不一定是對的:
redix = 31 的話,webkit 的長度最長可以到 1024!Firefox 只會到 11。

滿混亂的 Orz 總之如果確定是 spec 或是 implantation 的錯的話可以報出去,
看各位先進有沒有甚麼 idea。

再怎麼樣也可以丟上 WTFjs XDDDD


Tim

[1] http://www.ecmascript.org/docs.php, 4.3.19, pdf page 5
[2]
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Math/random
[3]
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number/toString

Received on Friday, 11 February 2011 04:36:46 UTC