震惊!计算机连0.3+0.6都算不对?浅谈IEEE754浮点数算数标准
>>> 0.3+0.6
0.8999999999999999
>>> 1-0.9
0.09999999999999998
>>> 0.1+0.1+0.1
0.30000000000000004
最初碰到这个问题是在写js的金额计算中遇到的,始终找不到是什么原因造成的,于是把锅甩给了JS:垃圾js浮点运算有bug!然后百度拷贝了一个解决浮点
运算的函数才解决了问题。
直到最近才发现,原来不仅js会“算不清”0.3+0.6,C#,JAVA,Python等很多语言都绕不过这个问题!
原来这是因为IEEE754浮点数算数标准,这个算数标准不使用小数点,而是使用分数和指数来表示小数,例如0.5会用1/2表示,0.75用1/2+1/4表示,0.875用1/2+1/4+1/8表示。然而有的小数无法使用有限的分数来表示,如0.1,使用1/16+1/32+1/256+1/512+...+1/8192+...表示,因此才造成了浮点数计算的误差。
怎么解决呢?C#,JAVA,Python都使用Decimal计算来替代浮点数的计算,尤其是涉及钱的计算!JS呢?百度一个处理函数调一下就ok啦~
这里附上js处理浮点预算的函数:
function add(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
return e = Math.pow(10, Math.max(c, d)), (mul(a, e) + mul(b, e)) / e;
}
function sub(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
return e = Math.pow(10, Math.max(c, d)), (mul(a, e) - mul(b, e)) / e;
}
function mul(a, b) {
var c = 0,
d = a.toString(),
e = b.toString();
try {
c += d.split(".")[1].length;
} catch (f) {}
try {
c += e.split(".")[1].length;
} catch (f) {}
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}
function div(a, b) {
var c, d, e = 0,
f = 0;
try {
e = a.toString().split(".")[1].length;
} catch (g) {}
try {
f = b.toString().split(".")[1].length;
} catch (g) {}
return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), mul(c / d, Math.pow(10, f - e));
}
震惊!计算机连0.3+0.6都算不对?浅谈IEEE754浮点数算数标准的更多相关文章
- Ibatis 3.0 之前使用的都是2.0 3.0与2.0的内容有很大的不同
以前用过ibatis2,但是听说ibatis3有较大的性能提升,而且设计也更合理,他不兼容ibatis2.尽管ibatis3还是beta10的状态,但还是打算直接使用ibatis3.0, ibatis ...
- IntelliJ IDEA 项目文件旁边都有0%classes,0% lines covered
IntelliJ IDEA 项目文件旁边都有0%classes,0% lines covered,解决方法:http://yayihouse.com/yayishuwu/chapter/2247
- 网上的CSS例子编写都不太严谨,如*{ margin:0;padding:0;}
margin:0;padding:0; 一般情况下不可以用 *{margin:0;padding:0;} 来适配. 保证自己的严谨代码编写风格.
- 开源搜索 Iveely Search Engine 0.6.0 发布 -- 黎明前的娇嫩
快两年了,Iveely Search Engine已经走过了5个版本的岁月,虽出生“贫寒”,没有任何开源基金会的支持,没有优秀的“干爹.干妈”,它凭着它的爱好者的支持,0.6.0终于破壳而出,7年前, ...
- c语言‘\0’ ,‘0’, “0” ,0之间的区别
首先比较一下‘\0’和‘0’的区别.有一个共同点就是它们都是字符,在c语言中,字符是按其所对应的ASCII码来存储的,一个字符占一个字节.请翻开你的ASCII字符集表吧,一般在你的C语言教材的附录上, ...
- Iveely Search Engine 0.4.0 的发布
千呼万唤始出来,Iveely Search Engine 0.4.0 的发布 经过无数个夜晚的奋战,以及无数个夜晚的失眠,Iveely Search Engine 0.4.0 终于熬出来了,这其中 ...
- 如何解决JavaScript中0.1+0.2不等于0.3
console.log(0.1+0.2===0.3)// true or false?? 在正常的数学逻辑思维中,0.1+0.2=0.3这个逻辑是正确的,但是在JavaScript中0.1+0.2!= ...
- Ubuntu16.04安装cuda9.0+cudnn7.0
Ubuntu16.04安装cuda9.0+cudnn7.0 这篇记录拖了好久,估计是去年6月份就已经安装过几遍,然后一方面因为俺比较懒,一方面后面没有经常在自己电脑上跑算法,比较少装cuda和cudn ...
- 为什么js中0.1+0.2不等于0.3,怎样处理使之相等?(转载)
为什么js中0.1+0.2不等于0.3,怎样处理使之相等? console.log(0.1+0.2===0.3)// true or false?? 在正常的数学逻辑思维中,0.1+0.2=0.3这个 ...
随机推荐
- jQuery学习之旅 Item5 $与jQuery对象
1.$符号的由来 $符号本质就是函数的名字. jquery源码分析 通过分析我们知道,在jquery里边不只可以使用$符号,还可以使用jQuery标志 解决冲突问题 有的项目是中间过渡项目(proto ...
- log4j的配置与使用
配置log4j的步骤如下: 1.导入jar包 如log4j-1.2.15.jar 2.在src下添加log4j.properties 使用时把下面内容中的注释去掉: //日志级别及位置 log4j.r ...
- github代码搜索技巧
github是一个非常丰富的资源,但是面对这丰富的资源很多人不知到怎么使用,更谈不上怎么贡献给他,我们需要使用github就要学习使用他的方法,学会了使用的方法,接受了他的这种观点我们才会慢慢的给他贡 ...
- Linux上配置使用iSCSI详细说明
本文详细介绍iSCSI相关的内容,以及在Linux上如何实现iSCSI. 第1章 iSCSI简介 1.1 scsi和iscsi 传统的SCSI技术是存储设备最基本的标准协议,但通常需要设备互相靠近并用 ...
- Prometheus监控数据格式学习
本文大纲: • prometheus metrics的概念• k/v的数据形式• prometheus exporter的使⽤(pull形式采集数据)• prometheus pushgateway的 ...
- java.lang.IllegalArgumentException异常 返回值类型的问题
java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return usi ...
- 【bzoj 3306】树
Description 给定一棵大小为 n 的有根点权树,支持以下操作: • 换根 • 修改点权 • 查询子树最小值 Input 第一行两个整数 n, Q ,分别表示树的大小和操作数. ...
- 【组合数学】Bzoj2916 [Poi1997]Monochromatic Triangles
Description 空间中有n个点,任意3个点不共线.每两个点用红线或者蓝线连接,如果一个三角形的三边颜色相同,那么称为同色三角形.给你一组数据,告诉你哪些点间有一条红线,计算同色三角形的总数. ...
- BZOJ_3894_文理分科&&BZOJ_2127_happiness_最小割
BZOJ_3894_文理分科_最小割 Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进 ...
- BZOJ_5296_[Cqoi2018]破解D-H协议_BSGS
BZOJ_5296_[Cqoi2018]破解D-H协议_BSGS Description Diffie-Hellman密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码 ...