javascript - 当小数与整数相乘的时候为什么会出现很长的小数。
怪我咯
怪我咯 2017-04-11 12:43:36
[JavaScript讨论组]

怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(7)
PHPz

请看sf上的这篇回答https://segmentfault.com/q/10...

ringa_lee

http://madscript.com/javascri...

ringa_lee

浮点数运算问题,可以google js 0.1+0.2 !=0.3 有很多文章

怪我咯

IEEE754规范导致的,不仅javasxcript这样,其他语言也有这种情况。对于2的倍数可以无损的表示,对于其他的就无力了。。。

ringa_lee

因为浮点数是以二进制来存储的,而用二进制表示十进制是不能精确表示的,即使浮点数的十进制有效数字比较少,那也不一定能用二进制精确表示。为什么呢?
首先浮点数小数位的二进制是这样对应的:
小数后1位:0.5 (2^-1)
小数后2位:0.25 (2^-2)
...
小数位n位:2^-n
也就是说,任何一个浮点数的小数部分都是由2^-1 ... 2^-n组合而成的,这样就能理解为什么有效位数少的浮点数也不能精确表示了,比如0.1,就无法用上面的位数组合而精确表示出来,不信把浮点数所有位数输出来试试:

(0.1).toFixed(20)

输出:'0.10000000000000000555'
而如果把0.1换成0.5,那就可以精确表示了,因为0.5可以用2^-1精确表示啊!同理,0.625也可以。
那我们平时为什么可以直接输出0.3呢?那是因为JavaScript输出的时候默认做了舍入处理

回到问题,把0.1*17的全部精度输出来:

(0.1*17).toFixed(20)

输出:'1.70000000000000017764'
很明显是做了舍入了。
那为什么0.1*13不会产生这样的现象呢?

(0.1*13).toFixed(20)

输出:'1.30000000000000004441'
对比一下就可以发现后面的有效数字比0.1*17少一位,舍入成0了。

高洛峰

数字在计算机中是十进制是以二进制存储的。
十进制中的有限不循环小数,在二进制中可能为无限循环小数
0.1(十进制) = 0.0001100110011001...(二进制)
17(十进制) = 10001(二进制)
计算机的计算结果也就是0.0001100110011001 * 10001(二进制)=1.1011001100110011(二进制) = 1.6999969482421875(十进制)

PHPz

其实这是js作浮点运算的一个bug
JavsScript中,变量在存储时并不区分numberfloat类型,而是统一按float存储。而javascript使用IEEE 754-2008 标准定义的64bit浮点格式存储number
按照IEEE 754的定义
decimal64对应的整形部分长度为10,小数部分长度为16,所以默认的计算结果为“1.7000000000000001”,如最后一个小数为0,则取1作为有效数字标志。
可以自己测试一下,把数字换成相对应的二进制:0.1(十进制) = 0.0001100110011001(二进制) 17(十进制) = 10001(二进制) 相乘运算。

解决方案地址:

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号