关于浮点型加减乘除运算不精确的问题
2018-03-09 18:53
826 查看
关于浮点型加减乘除运算不精确的问题
先举一个遇到这个错误的项目例子:
之前做一个小模块,由于后端接口还没有完成,需要自己搭建node服务,返回数据,功能需求是实时更新的,这个小模块中本人没有使用websocket,而是使用了轮询。
node服务关键代码如下(每3秒更新一次服务端数据,数据采用增加小数的方式,也就是涉及到了浮点型的加法)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/986ba50a167585a68611817b57e729c6)
前端vue中调用数据后,发现偶尔会出现以下情况:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/29a25f4db2a1e7a4625dc23d87de924d)
当时有点疑惑,搜索了很久都没找到方法,最后是大神同事告诉我的,问题出在浮点型的运算。
只要将node服务端代码修改以下,对浮点型长度做一下fixed就行。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/84beeab9d9cd498f7056f8da0112ee5d)
重启一下node服务(node my-server.js),然后会发现,不再出现此情况造成的bug:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/245a0ac885beca0fcea488444be4c3dd)
那么造成浮点型运算不精确的原因是什么呢?
对于二进制小数,小数点右边能表达的值是 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,浮点运算是不精确的,只能无限接近。
先举一个遇到这个错误的项目例子:
之前做一个小模块,由于后端接口还没有完成,需要自己搭建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,浮点运算是不精确的,只能无限接近。
相关文章推荐
- 浮点型加减乘除(解决浮点型运算精度丢失问题)
- 关于不能够精确的对浮点数进行运算的问题
- Java(其实是计算机系统的通病,而不单单是Java的问题,C、C++等任何语言都有这个问题)关于小数的运算结果,不正确不精确,原因剖析,及解决办法
- 关于商业运算中浮点型运算丢失精度问题
- 关于不能够精确的对浮点数进行运算的问题
- 关于C语言中无符号与有符号数之间运算问题
- 关于java中Double类型的运算精度问题
- 关于PHP运算精确度的问题
- 关于libsvm的Java和C版本的运算结果不一致的问题
- [导入]js 浮点运算表达式 精确计算(vb没有这个问题)
- 关于java中Double类型的运算精度问题
- 关于取余运算的一些细节问题
- 关于java中Double类型的运算精度问题
- [转帖]javascript做浮点数运算精确问题
- 关于整数和真分数的四则运算的算法,整数已通过,但真分数不能化到最简的问题求大神指导啊
- Java Puzzlers笔记--Puzzle 2: Time for a change 关于浮点型的问题
- 关于两个容积不同的瓶子中装水可以得到哪些精确值的问题的算法
- 关于c#除法运算的问题
- java BigDecimal实现精确加减乘除运算
- Java使用BigDecimal解决浮点型运算丢失精度的问题