Code Monkey home page Code Monkey logo

blog's People

Contributors

ericzyh avatar

Watchers

 avatar  avatar

blog's Issues

解密浮点数精度丢失

原文: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.具体在实际过程中对数字要求比较严苛的字段,尽量避免使用浮点数。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.