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

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

## 国际标准 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 浮点转二进制

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • 支付宝

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

    29 引用 • 347 回帖 • 1 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 141 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 708 关注
  • SpaceVim

    SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,以模块的方式组织管理插件以
    及相关配置,为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全,
    语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱
    即用的 Vim-IDE。

    3 引用 • 31 回帖 • 82 关注
  • SSL

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

    69 引用 • 190 回帖 • 483 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖 • 1 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    171 引用 • 813 回帖
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    379 引用 • 1221 回帖 • 590 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 2 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    87 引用 • 1206 回帖 • 449 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    140 引用 • 441 回帖
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 1 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    942 引用 • 1458 回帖 • 118 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 44 关注
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖
  • TextBundle

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

    1 引用 • 2 回帖 • 45 关注
  • gRpc
    10 引用 • 8 回帖 • 54 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    7 引用 • 26 回帖
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    86 引用 • 896 回帖
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 248 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 506 关注
  • Hprose

    Hprose 是一款先进的轻量级、跨语言、跨平台、无侵入式、高性能动态远程对象调用引擎库。它不仅简单易用,而且功能强大。你无需专门学习,只需看上几眼,就能用它轻松构建分布式应用系统。

    9 引用 • 17 回帖 • 611 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    76 引用 • 37 回帖