阅读:2209回复:10
关于 <input type="number" value="123456789123456789" />
在火狐里看是 123456789123457000 ,有谁知道这个转换的逻辑?
|
|
1楼#
发布于:2017-11-16 19:26
temp0.value → "123456789123456789"(字符串)
temp0.valueAsNumber → 123456789123456780(数值) 发现了吗? value 还是正确的 问题发生在从字符串转到数值的时候 根本原因在于 javascript 的 Number 是双精度 64 位浮点数 参考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number 就是超过了 Number.MAX_SAFE_INTEGER 导致精度丢失 其他浏览器应该也一样 这是由 ECMAScript 标准决定的 |
|
|
2楼#
发布于:2017-11-16 19:55
|
|
3楼#
发布于:2017-11-16 20:05
很简单。数值是按IEEE-754里规定的binary64这种64位浮点数存储的。能连续精确表示的整数只到2^53=90071992547409922。超过这个上限后,都会按一定规则进行舍入。
反正用这个规范存储数值的软件都会有这个问题,你到google上搜123456789123457000,会看到其他一些相关软件的讨论 |
|
4楼#
发布于:2017-11-16 20:11
|
|
5楼#
发布于:2017-11-16 20:48
https://html.spec.whatwg.org/multipage/input.html#number-state-(type=number)
“If the element is mutable, the user agent should allow the user to change the number represented by its value, as obtained from applying the rules for parsing floating-point number values to it.” 那个rules for parsing floating-point number values的最后是要求要做舍入的 |
|
6楼#
发布于:2017-11-16 21:17
非常感谢大家的回答!
|
|
7楼#
发布于:2017-11-16 21:17
|
|
8楼#
发布于:2017-11-16 22:33
|
|
|
9楼#
发布于:2017-11-16 22:41
taoww:https://html.spec.whatwg.org/multipage/input.html#number-state-(type=number)https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-floating-point-number-values Let rounded-value be the number in S that is closest to value, selecting the number with an even significand if there are two equally close values. Number.parseFloat('123456789123456789') 结果为 123456789123456780 123456789123456780 比 123456789123457000 更接近 123456789123456789 那么理应显示 123456789123456780 而非 123456789123457000 写了个测试页面 通过上下键调整 input type=number 元素的值时 value 会正确的加一减一 valueAsNumber 也会显示对应的数值 唯独 input 输入框的值显示异常 我觉得是 bug |
|
|
10楼#
发布于:2017-11-17 11:56
补上测试用页面
进一步测试后发现输入框的值与 Number.prototype.toLocaleString() 的值类似 都会缩水到 15 位有效数字(即使设置 maximumSignificantDigits 为 21) 设置 toLocaleString 的参数为 undefined, {useGrouping: false} 可以得到完全相同的结果 看来 firefox 不是直接显示原本就是字符串的 value 而会先转成浮点数(valusAsNumber)然后再通过类似 toLocaleString 的方法转回字符串 总之根本原因还是浮点数的精度有限 如何显示、默认取几位有效数字要看标准有没有规定并且浏览器又是如何实现的 firefox 目前这样肯定不妥 |
|
|