
如果我理解正确的话,JavaScript数字总是按照IEEE754国际标准以双精度浮点数的形式存储。这意味着它使用了52位的分数显着。但在上面的图片中,二进制数似乎是0.57,使用了54位。
另一件事是(如果我正确理解的话),二进制中的0.55也是一个重复的数字。但是为什么0.55 + 1 = 1.55 (没有损失)和0.57 + 1 = 1.5699999999999998

发布于 2019-03-22 00:43:21
这意味着它使用了52位的分数显着。但在上面的图片中,二进制数似乎是0.57,使用了54位。
JavaScript的Number类型,本质上是IEEE754基本64位二进制浮点,有53位意义.在“后继意义和”字段中编码52位。前导位通过指数域编码(指数字段1-2046表示前导位为1,指数字段0表示前导位为零,指数字段2047用于无穷大或NaN)。
您看到的.57值有53个重要位。领先的“0”由toString操作生成;它不是数字编码的一部分。
但为什么0.55 +1= 1.55 (无损失)和0.57 +1= 1.5699999999999998。
当JavaScript用默认规则格式化某些Number x以显示时,这些规则表示生成最短的十进制数字(以其有效数字表示,不包括像前导“0”这样的装饰)。当转换回Number格式时,产生x。此规则的目的包括:(a)始终确保显示唯一地标识确切的Number值是源值,(b)不使用超过完成(a)所需的更多数字。
因此,如果以十进制数(如.57 )开始,并将其转换为Number,则会得到一些值x,这是转换为以Number格式表示的数字的结果。然后,当x被格式化为显示时,您将得到原来的数字,因为要求生成转换回x的最短数字的规则自然会产生您开始使用的数字。
(但那个x并不完全代表0.57。与0.57最接近的double略低于它;参见计算器)。
另一方面,当您执行一些操作(如.57 + 1 )时,您正在执行一些算术,这些运算产生的数字y不以简单的十进制数开头。因此,当格式化这样的数字以显示时,规则可能需要使用更多的数字。换句话说。添加.57和1时,Number格式的结果与从1.57获得的结果不同。因此,要格式化.57 + 1的结果,JavaScript必须使用更多的数字来区分从1.57-they得到的数字是不同的,必须以不同的方式显示。
如果0.57完全可以表示为double,则之和的预四舍五入结果将精确地为1.57,因此1 + 0.57将舍入到与1.57相同的double。
但事实并非如此,实际上是1 + nearest_double(0.57) =
1.569999999999999951150186916493 (预四舍五入,而不是double),它归结为
1.56999999999999984012788445398。这些数字的十进制表示比我们需要区分意义的1ulp (最后一位的单位),甚至0.5 ulp最大值舍入误差所需要的数字还要多。
1.57循环到~1.57000000000000006217248937901,所以这不是打印1 + 0.57结果的选项。十进制字符串需要区分数字和相邻的binary64值。
恰好发生在.55 + 1中的四舍五入在将1.55转换为Number时得到了相同的数字,因此显示.55 + 1的结果会产生“1.55”。
发布于 2019-03-21 13:15:44
toString(2)将字符串打印到最后一个非零数字。
1.57与1+ 0.57有不同的位表示(但不是不可能得到结果1.57),
但是二进制文件中的1+ 0.55等于1.55,如下所示:
console.log(1.57)
console.log(1.57.toString(2))
console.log((1+.57).toString(2))
console.log("1.32 + 0.25 = ",1.32 + .25)
console.log((1.32 + .25).toString(2))
console.log(1.55)
console.log(1.55.toString(2))
console.log((1+.55).toString(2))
请记住,计算机对二进制数字执行操作,1.57或1.55只是人类可读的输出。
发布于 2019-03-21 13:06:25
Number.prototype.toString大致实现了ES262规范的以下部分:
7.1.12.1 NumberToString(m) 设n,k,s是整数,使得k≥1,10 ** k-1≤s< 10 ** k, S×10 ** n-k的数值为m, K越小越好。
因此,toString只是估计值,它不返回存储的确切字节。
您在控制台中看到的也不是一个精确的表示。
https://stackoverflow.com/questions/55280847
复制相似问题