Re: Math.random().toString(radix).substr(2) 拜肈

这个应该是toString(r)的算法不同。对于r=10以外的情况,ecma规范没有规定具体算法。

至于我们观察到的长度,因为原来是二进制,所以r为偶数时,非常容易转换,直接r/2一组转换即可,尾巴上补0即可。但当r为奇数时(比如31),就复杂了,除不尽!

比如0.5,二进制就是0.1(2),四进制就是0.2,16进制就是0.8。

但是三进制就是0.11111111111111111111111111111...

FF会限制长度,小数部分34位(根据r保留长度不同,可能是按照有效位数计算的)。而webkit则小数部分最长保留1024位。

我个人倾向于相信FF的算法更好一些。




2011/2/11 Timothy Chien <timdream@gmail.com>

> 年前寫了一個程式,很懶惰只在 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 18:14:19 UTC