国际 IEEE 754 标准,为啥会有精度缺失

本贴最后更新于 1647 天前,其中的信息可能已经渤澥桑田

## 国际标准 IEEE 754 浮点数的问题

- 整数的二进制比如 2 的二进制是 10 没疑问

- 小数的二进制比如 0.125 的二进制是 001 流程如下


//每次乘以2取整数部分,每次取完整数部分保留小数部分再乘以2

0.125

0.25=0.125*2  0

0.5=0.25*2    0

1.0=0.5*2     1

0.0=0.0*2     0

0.0           0

### 问题

1. 为啥这样存有什么原因,有什么好处和坏处

2. 为啥要指数表达法

3. 为啥要 补位

4. 为啥忽略 1

好了,上面这些问题,没事就是让你知道有这种问题就行,因为希望你在看下面的例子会产生这样的疑问,最后会一一解答

### IEEE 754 的内存结构

| 数符 | 阶码 | 尾数 |

| ---- | ---- | ----| 

| 1 位 | 8 位 | 23 位 |

整体的结构就是

0 00000000 00000000000000000000000 (问题1)

### 2.125 的内存二进制表达

1. 整数位 2 获取到它的二进制为 10

2. 0.125 的二进制表达为 001

3. 合并 2 个二进制就是 10.001

4. 二进制的指数表达法(问题2)为 1.0001 * 2^1 因为小数点 移了 1 位所以是 2^1

5. 补位 127 (问题31+127=128  128 二进制为 100000001 是 2^1 中的

6. 整体的二进制表示就是 0 10000000 00010000000000000000000  

其中数符 0 代表是正数,对应 1 代表负数, 阶码 10000000 是第五步产出的, 尾数 00010000000000000000000 是第四步的 1.0001 去除整数 1(问题4) 后补位到 23 位产出的

### 0.001 的内存二进制表达

1. 整数位 0 获取二进制为 0

2. 0.001 获取二进制为 00000000010000011000100100110111111111111111...

3. 合并就是 0.00000000010000011000100100110111111111111111...

4. 二进制的指数和表达法为 1.0000011000100100110111111111111111... * 2^-10 因为向 移动了 10 位所以是 2^-10

5. 补位 -10+127=117 二进制为=1110101, 注意这里是 7 位,下面会补 0

6. 整体的二进制表示就是 0 01110101 0000011000100100110111111111111111

内存结构同 2.125 分析过程

### 个人理解

1. 为啥这样存有什么原因,有什么好处和坏处

- 首先假如我们不这样存, 2.125 我们分成整数位和小数位分别存到内存中,那么一个整数位大小就能占用 32 位,小数位占用 32 位,总共一个 float 就占用 64 位

- 其次 0.001 这种用二进制表示如何表示,只能 00000000010000011000100100110111111111111111...,这样用 float 依然会产生精度缺失的问题, 还有就是假如 0000000......000001 这种情况怎么办,也就是前面的 0 就占了很多位,后面的数字根本存不了多大

- 好处就是上面的坏处, 占用内存小,精度依然缺失,可以存储这种很长 0 的数

2. 为啥去除指数表达式中的 1 (1.xxxxx)去除 1 留下 xxxxx,首先我们大致知道了二进制指数表达法,其本质就是为了去除小数部分的 0 开头的数据,因为 0 全部保留那么就像解答 1 中所说的那样 0 怎么去存储,这里的二进制指数表达式就很优雅的去除了 0,用的就是 2^x 来代表 0,然后把 1.xxx 中的 1 去除,因为一旦使用了二进制指数表达式,你的最前面一定是个 1,这也是这个 1 为啥可以去除
,这样 x 就可以代表偏移去除的 0 值,就可以单独代表很多小数

3. 上面 2 个例子的补位是啥操作 +127 
目前不知道

  1. 忽略 1 是因为前面都是 1 所以可以少存一位

### 总结

总的来讲,你要体会为啥要使用二进制的指数表达法,首先是为了去除整数和小数之间的区分,整体看成小数,然后用阶码来表示是变大了还是变小了,用尾数代表真正的数,然后要体会为啥是这样存储,本质就是为了存储二进制指数表达法

关联博客阅读: 

1. https://www.cnblogs.com/backwords/p/9826773.html 

2. https://blog.csdn.net/fwb330198372/article/details/70238982   

工具:

1. https://tool.lu/hexconvert/ 二进制转 10 进制

2. http://www.binaryconvert.com/result_float.html?decimal=048046048048049 浮点转二进制

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    69 引用 • 190 回帖 • 493 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 1 关注
  • gRpc
    10 引用 • 8 回帖 • 52 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 84 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    164 引用 • 594 回帖 • 1 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    138 引用 • 268 回帖 • 201 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 107 关注
  • 倾城之链
    23 引用 • 66 回帖 • 96 关注
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    228 引用 • 1450 回帖
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    106 引用 • 152 回帖 • 2 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖 • 2 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    123 引用 • 168 回帖
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 43 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    131 引用 • 1114 回帖 • 150 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖 • 1 关注
  • 笔记

    好记性不如烂笔头。

    303 引用 • 777 回帖
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 318 关注
  • 音乐

    你听到信仰的声音了么?

    59 引用 • 509 回帖
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 21 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 393 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 642 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    535 引用 • 672 回帖
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    75 引用 • 145 回帖
  • 反馈

    Communication channel for makers and users.

    123 引用 • 906 回帖 • 191 关注
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    91 引用 • 751 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 25 关注