ericzyh / blog Goto Github PK
View Code? Open in Web Editor NEWmy blog
my blog
原文:http://www.zhaoyuhao.com/notes/show/206
之前对浮点数精度丢失一直有所耳闻,可是从没有深入的研究,今天在微博看到鸟哥的博文-PHP浮点数的一个常见问题的解答,文章写的有点简单,却引发了我对浮点数的刨根究底的热情,在网上找了几篇资料,总算让自己理解的比较透彻了。
注:下文中提到浮点数均为双精度(64位)浮点数。
一、迷思
我们知道用64bit表示整数,数据范围应该是在 -2^63 ~ +2^63 之间 。但是如果用同样64bit表示浮点数,数据范围变为了 -1.7976931348623157_10^308 ~ +1.7976931348623157_10^308 , 数据区间放大了无数倍。
这种不符合常理逻辑思维的放大,容易让人陷入迷失
在chrome控制台输入Number.MAX_VALUE 和 Number.MIN_VALUE 分别可以查看64位浮点数的最大和最小值
二、浮点数的存储方式
为了破解迷思,必须从最基础的浮点存储方式出发,下图以Number.MAXVALUE为例,说明浮点数是如何存储在64bit中:
三、精度丢失的罪魁祸首
细心的同学可能已经发现,有效数字只有52bit,偏移量最大可以是1023,也就是说浮点数把原本只有52bit的数字空间,通过偏移变成了1023bit。当偏移量为1023时后边972位就完全失去精度了。
在chrome控制台输入
Number.MAX_VALUE == Number.MAX_VALUE-Number.MAX_VALUE/Math.pow(2,54)
,可以推测Number.MAX_VALUE的精度丢失了972位,同理当偏移量为1022时精度丢失971位,当偏移量为53时,精度偏移2^1,可以通过js很简单的证实:
Math.pow(2,53) == Math.pow(2,53) + 1``Math.pow(2,53) != Math.pow(2,53) + 1
四、小数的情况
前文为了方便理解,都是用整数来讲解,但浮点数的目的还是为了存储小数。小数的情况比整数复杂一些,不管数字大小都可能出现精度丢失的情况。比如在chrome控制台输入 0.4+0.2 结果等于 0.6000000000000001 。
用10进制的例子来类比2进制:
1/3 + 1/7 = 0.33333333... + 0.1428571428571..
因为1/3和1/7是无限循环小数,所以他们相加得到的一定也是一个无限循环小数,把无限小数存储为有限小数时就存在精度丢失。
同理,0.2但是转化成二进制也成了无限循环小数 0.0011001100110011....(小数二进制装换请自行补脑) 。于是造成了精度的丢失。
五、总结
总而言之,造成精度丢失的罪魁祸首就是偏移。数字越大(或者小数点后面位数越多),精度丢失就约严重。
个人觉得有几种情况不会生产精度丢失,欢迎补充:
1.数字是小于2^52的整数
2.不会变成二进制无限循环的小数 如:0.5 0.05 等等...
so.具体在实际过程中对数字要求比较严苛的字段,尽量避免使用浮点数。
first blog
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.