一个数字截取引发的精度问题(四)

这篇是精度问题的最后一篇,要是想看前面的,请看微信历史记录。

做前端的都感觉JS这语言巨坑无比,兼容性让你摸不到头脑,甚至还会让你脱发。一些初学者遇到:

0.1 + 0.2 = 0.30000000000000004

都会觉得这JS太TM坑了,一个小数计算都不会。可是我想说,这"锅"JS不背!其实和JS采用的数值存储 IEEE754 规范有关,所有采用此规范的语言都会有此问题并不是JS的"锅"。

IEEE754

IEEE浮点数算术标准(IEEE 754)是最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用,单精确度(32位)、双精确度(64位)、延伸单精确度(43位以上,很少使用)与延伸双精确度(79位元以上,通常以80位元实做)

计算机中是用有限的连续字节保存浮点数的。 JS采用64位(双精度)存储数据,在 IEEE 标准中,浮点数是将所有二进制位分割为特定宽度的符号域(S),指数域(E)和尾数域(F)三个域, 其中保存的值分别用于表示给定二进制浮点数中的符号,指数和尾数。

根据国际标准IEEE 754,任意一个二进制浮点数V可以表示成下面的形式:

V = (-1)^s×M×2^E
  1. (-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
  2. M表示有效数字,大于等于1,小于2,但整数部分的1可以省略。
  3. 2^E表示指数位。 对于十进制的5.25对应的二进制为:101.01,相当于: 1.0101*2^2。所以,S为0,M为1.0101,E为2。 而 -5.25=-101.01=-1.0101*2^2。所以S为1,M为1.0101,E为2。

复习一下十进制转二进制:

口诀

整数部分除2取余,由下到上;小数部分乘2取整,由上到下。

0.1 在计算机中如何存储?

首先 0.1 转化为二进制:0.000110011(0011循环)套用公式可得:

(-1)^0*1.1001*2^-4

所以 s:0,M:1.1001(循环1001),E:-4。

由于小数位仅储存 52bit, 储存时会将超出精度部分进行"零舍一入",

无限精确值:

1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001

实际储存值:

1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010

此处精度已经丢失一次。最后0.1实际存储为:

0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010

同理计算出0.2的实际存储值(同样也存在精度丢失):

0.001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010

两数相加得:

0.01001100110011001100110011001100110011001100110011001110

再转为十进制:0.30000000000000004。

在线转换工具:http://tool.oschina.net/hexconvert。

原文发布于微信公众号 - 前端黑板报(FeHeiBanBao)

原文发表时间:2017-03-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云端架构

【云端架构】教你口算MD5算法

对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成...

59214
来自专栏程序生活

Tensorflow教程(十三) tf.Variable() 和tf.get_variable()1 简介2 区别3 实例

2113
来自专栏小L的魔法馆

新疆大学ACM-ICPC程序设计竞赛五月月赛(同步赛)--B-杨老师的游戏

4289
来自专栏mathor

搜索(6)

 题目大意是在一个nxn的方阵地图上,每一个方格都标记+号或者-号,要从A点到B点。题目要求移动路线要+-交替,问怎么移动从A到B才是最短路径?  同样...

1373
来自专栏架构之路

并查集Union-find及其在最小生成树中的应用

并查集是一种用途广泛的数据结构,能够快速地处理集合的合并和查询问题,并且实现起来非常方便,在很多场合中都有着非常巧妙的应用,。 本文首先介绍并查集的定义、原理及...

3624
来自专栏Python小屋

详解Python列表推导式

列表推导式可以使用非常简洁的方式对列表或其他可迭代对象的元素进行遍历和过滤,快速生成满足特定需求的列表,代码具有非常强的可读性,是Python程序开发时应用最多...

4204
来自专栏Petrichor的专栏

python: random模块

  在numpy 和 tensorflow 中有 相同功能 的实现, 见 《tensorflow: Constants, Sequences, and Ra...

2011
来自专栏决胜机器学习

PHP数据结构(五) ——数组的压缩与转置

PHP数据结构(五)——数组的压缩与转置 (原创内容,转载请注明来源,谢谢) 1、数组可以看作是多个线性表组成的数据结构,二维数组可以有两种存储方式:一种是以行...

40411
来自专栏王肖的UT

GLSL-内置函数

5413
来自专栏chenjx85的技术专栏

leetcode-73-矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。

2341

扫码关注云+社区

领取腾讯云代金券