关于浮点型加减乘除运算不精确的问题

关于浮点型加减乘除运算不精确的问题

先举一个遇到这个错误的项目例子:

之前做一个小模块,由于后端接口还没有完成,需要自己搭建node服务,返回数据,功能需求是实时更新的,这个小模块中本人没有使用websocket,而是使用了轮询。

node服务关键代码如下(每3秒更新一次服务端数据,数据采用增加小数的方式,也就是涉及到了浮点型的加法)

前端vue中调用数据后,发现偶尔会出现以下情况:

当时有点疑惑,搜索了很久都没找到方法,最后是大神同事告诉我的,问题出在浮点型的运算。

只要将node服务端代码修改以下,对浮点型长度做一下fixed就行。

重启一下node服务(node my-server.js),然后会发现,不再出现此情况造成的bug:


那么造成浮点型运算不精确的原因是什么呢?

对于二进制小数,小数点右边能表达的值是 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 … 1/(2^n)。所有这些小数都是一点一点的拼凑出来的一个近似的数值, 所有才会不准确的。

举个例子, 现在用二进制来表示十进制的1.2:
1.01 = 1 + 1/4 = 1.25 , 偏大
1.001 = 1 + 1/8 = 1.125 , 偏小
1.0011 = 1 + 1/8 + 1/16 = 1.1875 , 偏小
1.001101 = 1 + 1/8+ 1/16 + 1/64 = 1.203125 , 偏大
1.0011001 = 1 + 1/8 + 1/16 + 1/128 = 1.1953125 , 偏小
1.00110011 = 1 + 1/8+1/16+1/128+1/256 = 1.19921875 , 偏小,但很接近
越来越接近……..
这就是所谓的用二进制小数没法精确表达10进制小数的意思。

在控制台输入17.9*100,会得到1789.9999999999998,浮点运算是不精确的,只能无限接近。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值