关于浮点型加减乘除运算不精确的问题
关于浮点型加减乘除运算不精确的问题先举一个遇到这个错误的项目例子:之前做一个小模块,由于后端接口还没有完成,需要自己搭建node服务,返回数据,功能需求是实时更新的,这个小模块中本人没有使用websocket,而是使用了轮询。node服务关键代码如下(每3秒更新一次服务端数据,数据采用增加小数的方式,也就是涉及到了浮点型的加法)前端vue中调用数据后,发现偶尔会出现以下情况:当时有点疑惑,搜索了很
关于浮点型加减乘除运算不精确的问题
先举一个遇到这个错误的项目例子:
之前做一个小模块,由于后端接口还没有完成,需要自己搭建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进制小数的意思。
更多推荐
所有评论(0)