为什么Chrome在(.1).toString(3)的点后产生1099位数? [英] Why does Chrome produce 1099 digits after the dot for (.1).toString(3)?

查看:117
本文介绍了为什么Chrome在(.1).toString(3)的点后产生1099位数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得这只是一个无害的bug,但我仍然想知道发生了什么。

I have a feeling that this is a just a harmless bug but I'd still like to understand what's going on.

我正在玩一些代码来渲染画布上的 Peano曲线,当我注意到函数是在Chrome中返回荒谬的长字符串。仔细观察,结果表达式

I was playing with some code to render a Peano curve on a canvas that involves expressing logical coordinates in base 3 when I noticed that a function was returning absurdly long strings in Chrome. Looking more closely, it turns out that the expression

(.1).toString(3)

在Chrome中评估


0。 2001022112012202110101212100011220000220200122222102201100202101012110201221202211220201111021112112201120101121122212112220211110002020120201022022121210120002202021212000101222221101122201001100021211101012101011202020110010112202201201001020212002021112020021121202000000222122210022012001201

0.0022002200220022002200220022002201000021002100001101010002022011202012121102122020112120001020210222101201120010221010101202020200221020101002002101100100002022210010220022021021221021100020120102202020200110002220220012001021022020001120220101001022112120121220210122121200121200122212100110210102202000012021211200222221101111211122012121111202211210010022212100002210220210122200201120220011210120110011120000011011001010110022012102001102020210211202111001002101200102022221112212012011000022110022020001100112212102102100111000222211012211220200112120002100121210000222002201120220111022021120022101112201220001101012112201211010010110122011201120022210102021100002000121020120001112122222220201200220012211122001022022001222011221100212001100010200001211022021120210222110022221202002120011210220012001022112012202110101212100011220000220200122222102201100202101012110201221202211220201111021112112201120101121122212112220211110002020120201022022121210120002202021212000101222221101122201001100021211101012101011202020110010112202201201001020212002021112020021121202000000222122210022012001201

如在这里看到: http://jsfiddle.net/zvp8osm8/

据我所知,在这种情况下,只有点后面的前33位才有意义,休息看起来像没有可识别模式的随机垃圾。
类似的结果,在为不同的基数生成点之后有1099(!)个数字,而且指数也类似于(10000000000.1).toString(3)(7)的ToString(7)。其他值如(。5).toString(3)也会产生很长的字符串,但数字都有意义。

For what I can tell, only the first 33 digits after the dot make sense in this case, the rest looks like random garbage without a recognizable pattern. Similar results with 1099 (!) digits after the dot are produced for different bases and exponents too like (10000000000.1).toString(3) or (.7).toString(7). Other values like (.5).toString(3) also produce strings that long, but the digits all make sense.

除了Opera之外的其他浏览器在每种情况下都会产生合理数量的数字,这让我觉得问题出在Chrome的Javascript引擎中。

Other browsers with the exception of Opera only produce a reasonable number of digits in every case, which makes me think that the problem is in the Chrome's Javascript engine.

我现在有两个问题:


  • 为什么基数3中的十进制数表示在Chrome中包含这么多无关紧要的数字?

  • 随机数字可能来自哪里?

推荐答案

在您显示的特定情况下,看起来数字是使用以下天真算法生成的,从 x = .1 开始。

For the particular case you show, it looks as though digits are being generated using the following naive algorithm, starting with x = .1.


  1. 乘以 x 乘以3.

  2. 提取结果的整数和小数部分。

  3. 将整数部分输出为数字,并将 x 替换为小数部分。
  4. 重复步骤1到3直到无聊(或直到达到某个预设限制)。

  1. Multiply x by 3.
  2. Extract the integer and fractional parts of the result.
  3. Output the integer part as a digit, and replace x with the fractional part.
  4. Repeat steps 1 to 3 until bored (or until some preset limit is achieved).

这在数学上可以正常工作,但在浮点世界中,这完全是胡说八道,当然,因为乘以3和随后的舍入到最近的浮点数可能会引入一个小错误,并且在30位左右之后错误已经完全淹没了原始数字,我们只是变得垃圾。

This would work just fine mathematically, but in the world of floating-point this is utter nonsense, of course, since the multiplication by 3 and subsequent round to the nearest floating-point number potentially introduces a small error, and after 30 digits or so the error has completely swamped the original digits, and we're just getting garbage.

据推测,在初始数字的情况下,还有一些处理数字的方法绝对值大于 1.0 ,但没有样本输出,我不会猜测算法是什么。

Presumably there's also some way of handling the digits before the point for the case where the initial number is larger than 1.0 in absolute value, but without sample output, I'm not going to guess what that algorithm is.

为证明上述内容,这里有一些Python中的代码,其输出与问题中给出的完全匹配。在这里, modf 是提取Python float的小数部分和整数部分的操作。

To justify the above, here's some code in Python whose output exactly matches that given in the question. Here, modf is the operation that extracts the fractional and integral parts of a Python float.

>>> from math import modf
>>> x = 0.1
>>> digits = []
>>> for _ in xrange(1099):
...     x, digit = modf(3.0 * x)
...     digits.append(str(int(digit)))
... 
>>> print('0.' + ''.join(digits))

输出:


0。 10201221202211220201111021112112201120101121122212112220211110002020120201022022121210120002202021212000101222221101122201001100021211101012101011202020110010112202201201001020212002021112020021121202000000222122210022012001201

0.0022002200220022002200220022002201000021002100001101010002022011202012121102122020112120001020210222101201120010221010101202020200221020101002002101100100002022210010220022021021221021100020120102202020200110002220220012001021022020001120220101001022112120121220210122121200121200122212100110210102202000012021211200222221101111211122012121111202211210010022212100002210220210122200201120220011210120110011120000011011001010110022012102001102020210211202111001002101200102022221112212012011000022110022020001100112212102102100111000222211012211220200112120002100121210000222002201120220111022021120022101112201220001101012112201211010010110122011201120022210102021100002000121020120001112122222220201200220012211122001022022001222011221100212001100010200001211022021120210222110022221202002120011210220012001022112012202110101212100011220000220200122222102201100202101012110201221202211220201111021112112201120101121122212112220211110002020120201022022121210120002202021212000101222221101122201001100021211101012101011202020110010112202201201001020212002021112020021121202000000222122210022012001201

这应该回答你的问题之一:即在随机数字从何而来。我无法回答为什么Chrome选择输出这么多数字的问题。

This should answer one of your questions: namely where the random digits come from. I can't answer the question of why Chrome chooses to output so many digits.

这篇关于为什么Chrome在(.1).toString(3)的点后产生1099位数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆