《深入理解计算机系统》学习笔记 - 第四课 - 浮点数

Floating Point 浮点数

文章目录

  • Floating Point 浮点数
    • 分数二进制示例
    • 能代表的数
    • 浮点数的表示方式
      • 浮点数编码
        • 规格化值
          • 规格化值编码示例
        • 非规格化的值
        • 特殊值
    • 示例
    • IEEE 编码的一些特殊属性
    • 四舍五入,相加,相乘
      • 四舍五入
        • 四舍五入的模式
        • 二进制数的四舍五入
    • 浮点数乘积
    • 浮点数加法
    • 浮点数的一些数学性质
    • 浮点数在C中
      • 类型转换的比较
    • 《深入理解计算机系统》书籍学习笔记

浮点主要通过移动二进制小数点来表示尽可能大的取值范围,兼顾尽可能高的精度,同时还要受到位数有限的限制。

分数二进制示例

值          二进制表示       十进制
5  3/4      101.11           2^2 + 2^0 + 1/2^1 + 1/2^2 
2  7/8      10.111           2^1 + 1/2^1 + 1/2^2 + 1/2^3
1  7/16     1.0111           2^0 + 1/2^2 + 1/2^3 + 1/2^4
  • 分数除以2,就是小数点二进制右移1位。
  • 乘以2, 就是小数点左移1位
  • 数字0.111111111… 小于 1,无限接近于1
    • 1/2 + 1/4 + 1/8 + … + 1/2^i + … -> 1.0
    • 记为 1.0 - ε

能代表的数

  • 只能精确地表示x/2k形式的数字

  • 其他有理数有重复的位表示

值      二进制表达                      十进制
1/3     0.01010101010101[01]...         1/2^2 + 1/2^4 + 1/2^6 + 1/2^8 + ...
1/5     0.001100110011[0011]...         1/2^3 + 1/2^4 + 1/2^7 + 1/2^8 + ...
1/10    0.0001100110011[0011]...        1/2^4 + 1/2^5 + 1/2^8 + 1/2^9 + ...

浮点数的表示方式

同一标准:

(–1)^s*M*2^E

看着是不是像二进制科学计数法。

  • 符号位s: 决定了数是正数还是负数
  • 显著值M(mantissa,小数部分): 通常是在[1.0,2.0]范围内的分数值。
  • 指数E(exponent): 以2的幂表示值的权重

浮点数编码

在这里插入图片描述

  • s 符号位
  • exp 字段编码E(但是不等于E)
  • frac 字段编码M (但是不等于M)

不同精度:

  • 单精度:32 位(bits)
    字段所占位数: s:exp:frac -> 1:8:23

  • 双精度: 64 位(bits)
    字段所占位数: s:exp:frac -> 1:11:52

规格化值

当exp != 000…0 , 并且exp != 111…1

指数编码有一个偏置值:E = Exp - Bias
Exp : exp字段,无符号值
Bias = 2^(k-1) -1
k 表示指数的位数

  • 取值范围
    单精度:k=8, Bias = 2^(8-1) - 1 = 127 (1 <= Exp <= 254, -126 <= E <= 127)
    双精度: k=11,Bias = 2^(11-1) - 1 = 1023 (1 <= Exp <= 2046, -1022 <= E <= 1023)

  • 用隐含前导编码的有效数 1: M = 1.xxxxxx 二进制
    xxxxx: 表示frac 字段编码
    最小值:frac = 000…0(M=1.0)
    最大值:frac = 111…1(M=2.0-ε)

注意: M 是固定前面有一个1,所以最小值才是1开始。

规格化值编码示例

  • Float F = 15213.0
    15213 十进制 = 11101101101101 二进制
    = 1.1101101101101 * 2^13 科学计数法

  • 有效数
    M(小数) = 1.1101101101101 二进制
    frac(小数部分编码) = 1101101101101 0000000000 二进制

  • 指数
    E = 13
    Bias = 127
    Exp = 140 = 10001100 二进制

  • 结果
    在这里插入图片描述

非规格化的值

非规格化条件:exp = 000…0

指数值:E = 1 - Bias(注意:不是E = 0 - Bias)
以隐含前导0编码的有效数:M = 0.xxx…x

案例:

  • exp = 000…0, frac = 000…0
    代表0值
  • exp = 000…0, frac != 000…0
    最接近0.0的数字。
    平均间隔。
特殊值

特殊值条件:exp = 111…1

案例:

  • exp = 111…1, frac = 000…0
    代表无穷大。
    操作溢出。
    例如:正无穷大:1.0/0.0 = -1.0/-0.0 , 负无穷大:1.0/-0.0

  • exp = 111…1, frac != 000…0
    Not-a-Number(NaN)
    表示无法确定数值时的情况。
    例如:sqrt(-1), 无穷大*0

示例

我们用简单的8位浮点数表示法,来理解浮点数。
在这里插入图片描述

s: 1位符号位
exp: 4位指数位, 偏置位bias=2^(4-1)-1=7
frac: 3位小数位

s exp  frac E Value                 计算                                        备注
0 0000 000 -6 0                     (-1)^0 * 0 * 2^(-6)
0 0000 001 -6 1/8*1/64 = 1/512      (-1)^0 * 2^(-3) * 2^(-6)                    // 最接近0值
0 0000 010 -6 2/8*1/64 = 2/512      (-1)^0 * 2^(-2) * 2^(-6)        
…
0 0000 110 -6 6/8*1/64 = 6/512      (-1)^0 * 2^(-1)*2^(-2) * 2^(-6)  
0 0000 111 -6 7/8*1/64 = 7/512      (-1)^0 * 2^(-1)*2^(-2)* 2^(-3) * 2^(-6)     // 最大的非规格化值
0 0001 000 -6 8/8*1/64 = 8/512      (-1)^0 * 1 * 2^(-6)                             // 最小的规格化值
0 0001 001 -6 9/8*1/64 = 9/512      (-1)^0 * (1 + 2^(-3)) * 2^(-6)  
…
0 0110 110 -1 14/8*1/2 = 14/16      (-1)^0 * (1 + 2^(-1)*2^(-2)) * 2^(-1)  
0 0110 111 -1 15/8*1/2 = 15/16      (-1)^0 * (1 + 2^(-1)*2^(-2)* 2^(-3)) * 2^(-1)                // 最接近1的(小于1的数)
0 0111 000 0  8/8*1 = 1             (-1)^0 * 1 * 2^0
0 0111 001 0  9/8*1 = 9/8           (-1)^0 * (1 + 2^(-3)) * 2^0                // 最接近1的(大于1的数)
0 0111 010 0  10/8*1 = 10/8         (-1)^0 * (1 + 2^(-2)) * 2^0
…
0 1110 110 7  14/8*128 = 224        (-1)^0 * (1 + 2^(-1)*2^(-2)) * 2^7
0 1110 111 7  15/8*128 = 240        (-1)^0 * (1 + 2^(-1)*2^(-2)* 2^(-3)) * 2^7             // 最大的规格化数
0 1111 000 7  inf                   

值的计算公式:v = (–1)^s * M * 2^E
规格化数: E = Exp – Bias
非规格化数: E = 1 – Bias

IEEE 编码的一些特殊属性

  • 浮点数(FP)的0值和整型0值一样
    所有的位都是0

  • 除了非数字(NaN)之外,你可以比较任何浮点数。
    当作无符号数来比较。

四舍五入,相加,相乘

四舍五入

基本思想:

  • 先计算得到一个准确的值
  • 然后根据你期望的精度进行处理
    • 如果指数太大的化,可能会溢出
    • 可能需要四舍五入来满足小数位数(frac)
四舍五入的模式
                $1.40   $1.60   $1.50   $2.50   –$1.50
向0舍入         $1      $1      $1      $2      –$1
向下舍入        $1      $1      $1      $2      –$2
向上舍入        $2      $2      $2      $3      –$1
向偶数舍入      $1      $2      $2      $2      –$2

向0舍入:向0的方向舍去小数。
向下舍入:类似向下取整
向上舍入:类似向上取整
向偶数舍入:在四舍五入的基础上,考虑向偶数靠近,主要是在中位数时的处理方式和四舍五入不同。

二进制数的四舍五入

奇数是1,0是偶数。
二进制中间数100…,十进制中间数是500…

精度时小数后两位:

Value   Binary  Rounded     Action  Rounded     Value
2       3/32    10.000112   10.002  (<1/2—down) 2
2       3/16    10.001102   10.012  (>1/2—up)   2 1/4
2       7/8     10.111002   11.002  ( 1/2—up)   3
2       5/8     10.101002   10.102  ( 1/2—down) 2 1/2

浮点数乘积

相乘:((–1)^s1 * M1 * 2^E1) x ((–1)^s2 * M2 * 2^E2)
准确值:: (–1)^s * M * 2^E
符号位 s: s1 ^ s2
有效位 M: M1 x M2
指数位 E: E1 + E2

修正:

  • 如果 M >= 2, M 右移,增加E
  • 如果E 超出范围,溢出
  • 四舍五入 M 来符合精度要求。

浮点数加法

相加:((–1)^s1 * M1 * 2^E1) + ((–1)^s2 * M2 * 2^E2)
假设:E1 > E2

准确值:: (–1)^s * M * 2^E
符号位 s, 有效位 M: 对齐相加
指数位E: E1

修正:

  • 如果 M >= 2, 右移M, 增加E。(小数点右移)
  • 如果 M < 1, 左移 M 的 k 个位置, 减少 E 的 k。(小数点左移)
  • 如果E超出范围溢出
  • 将 M 适应小数(frac)精度

浮点数的一些数学性质

浮点数加法的数学性质:

  • 与阿贝尔群的比较
    • 加法封闭: 满足
      • 但是可能产生 无穷大和NaN
    • 结合律:满足
    • 交换律:不满足
      • 进行四舍五入时,可能溢出和不精确
      • (3.14+1e10)-1e10 = 0, 3.14+(1e10-1e10) = 3.14
      • 每个元素都有可加逆:几乎满足
        • 除了无穷大和NaN
  • 单调性
    • a ≥ b ⇒ a+c ≥ b+c : 几乎满足
      • 除了无穷大和NaN

浮点数乘法的数学性质和加法是类似的。

浮点数在C中

无符号和有符号的转换,从未改变过位的表示(位上的实际值),只是改变了某些位的解释方式。

整数,单精度浮点数,双进度浮点数的转换,位的表示发生了变化(实际值改变了),会对位的值产生实际影响。

  • double/float -> int
    • 截取小数部分
    • 就像向0舍入
  • int -> double
    精确的转换,只要int(32) <= 53 位大小。
  • int -> float
    将会进行四舍五入操作。

类型转换的比较

三个不同类型的变量:

int x = …;
float f = …;
double d = …;

一些特性的比较:

* x == (int)(float) x           // false
• x == (int)(double) x          // true
• f == (float)(double) f        // true
• d == (double)(float) d        // false
• f == -(-f);                   // true
• 2/3 == 2/3.0                  // false. 2/3=0 整数, 2/3.0 是浮点数。
• d < 0.0 ⇒ ((d*2) < 0.0)       // true, 浮点数即使溢出也是负无穷大数
• d > f ⇒ -f > -d               //  true, 单调性
• d * d >= 0.0                  // true 
• (d+f)-d == f                  // false, 不满足结合律

《深入理解计算机系统》书籍学习笔记

《深入理解计算机系统》学习笔记 - 第一课 - 课程简介
《深入理解计算机系统》学习笔记 - 第二课 - 位,字节和整型
《深入理解计算机系统》学习笔记 - 第三课 - 位,字节和整型
《深入理解计算机系统》学习笔记 - 第四课 - 浮点数
《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/234398.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Terminator的layout设置(一个新的一键启动思路)

首先你得有terminator&#xff1a; sudo apt install terminator然后就能使用了&#xff0c;我一般喜欢修改它原本的水平和垂直分割&#xff1a;用ctrlshifta和ctrlshifts 把屏幕先分成多块&#xff1a; 比如是这样的&#xff0c;接下来 右键->点击Preference 弹框中上方标…

C++:this指针

目录 前言 成员函数返回this指向的对象本身时&#xff0c;为什是返回引用类型&#xff1f; 成员函数返回this对象本身时&#xff0c;内部通常会通过拷贝构造函数来创建一个临时对象&#xff1f; 总结 前言 c通过提供特殊的对象指针&#xff0c;this指针 指向被调用的成员函…

Ubuntu下安装SDL

源码下载地址&#xff08;SDL version 2.0.14&#xff09;&#xff1a;https://www.libsdl.org/release/SDL2-2.0.14.tar.gz 将源码包拷贝到系统里 使用命令解压 tar -zxvf SDL2-2.0.14.tar.gz 解压得到文件夹 SDL2-2.0.14 进入文件夹 执行命令 ./configure 执行命令 make…

Linux环境下socket本地通信

最近项目有用到了socket本地通信&#xff0c;故复习一下。之前都是基于本地虚拟机的ip地址通信的&#xff0c;现在项目&#xff0c;Linux单板上面有2个进程需要通信&#xff0c;故用到了本地socket通信&#xff0c;主要其实就是用了sockfd,文件描述符&#xff0c;也叫句柄。 服…

Android系统中使用Cunit测试C/C++接口

Android系统中使用Cunit测试C/C接口 Cunit是C/C语言的单元测试框架&#xff0c;但常用于Windows和Linux开发中。 Android系统中经常有jni、so库、hal service等都是C/C实现&#xff0c;本文讲解如何将Cunit嵌入Android中&#xff0c;用于测试一些C/C api。 Cunit简介 Cunit是很…

什么是CDN?用了CDN一定会更快吗?

文章目录 前言CDN是什么?CDN的工作原理为什么要加个CNAME那么麻烦&#xff1f;怎么知道哪个服务器IP里调用方最近&#xff1f; 回源是什么回源是什么&#xff1f;那还有哪些情况会发生回源呢&#xff1f; 怎么判断是否发生回源用了CDN一定比不用的更快吗&#xff1f;什么情况下…

C语言笔试例题_指针专练30题(附答案解析)

C语言笔试例题_指针专练30题(附答案解析) 指针一直是C语言的灵魂所在&#xff0c;是掌握C语言的必经之路&#xff0c;收集30道C语言指针题目分享给大家&#xff0c;测试环境位64位ubuntu18.04环境&#xff0c;如有错误&#xff0c;恳请指出&#xff0c;文明讨论&#xff01;&am…

【git】关于git二三事

文章目录 前言一、创建版本库1.通过命令 git init 把这个目录变成git可以管理的仓库2.将修改的内容添加到版本库2.1 git add .2.2 git commit -m "Xxxx"2.3 git status 2.4 git diff readme.txt3.版本回退3.1 git log3.2 git reset --hard HEAD^ 二、理解工作区与暂存…

面试 Redis 八股文十问十答第一期

面试 Redis 八股文十问十答第一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1.Redis数据类型有哪些? String&#xff08;字符串&#xff09;&#xff1a;是…

win11 CUDA(12.3) + cuDNN(12.x) 卸载

win11 CUDA&#xff08;12.3&#xff09; cuDNN&#xff08;12.x&#xff09;卸载 信息介绍卸载 信息介绍 本文是对应 win11RTX4070Ti 安装 CUDA cuDNN&#xff08;图文教程&#xff09; 的卸载 卸载 控制面板 --> 程序 --> 卸载程序 卸载掉图中红框内的&#xff0c…

四. 基于环视Camera的BEV感知算法-环视背景介绍

目录 前言0. 简述1. 环视背景介绍2. 环视思路3. 主流基于环视Camera的算法详解总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Camer…

【杂项】程序的执行目录和程序的当前目录

当32位应用程序运行时&#xff0c;系统将为它分配一个4GB的地址空间&#xff0c;加载模块会会分析该应用程序的输入信息&#xff0c;从中找到程序将要访问的动态链接库信息&#xff0c;在用户机器上搜索这些动态链接库&#xff0c;进而加载它们&#xff0c;搜索的顺序依次是 程…

基于C++11标准的Vector容器与多维数组编程规范学习

一、基本概念 泛型编程&#xff1a;所谓泛型程序设计&#xff0c;就是编写不依赖于具体数据类型的程序。C中&#xff0c;模板是泛型编程的主要工具。泛型程序设计的主要思想是将算法从特定的数据结构中抽象出来&#xff0c;使算法成为通用的、可以作用于各种不同的数据结构。以…

Vue3 使用图片涂鸦插件

一、安装插件 npm i toast-ui/vue-image-editor npm i tui-code-snippet npm i tui-image-editor Image-editor | TOAST UI :: Make Your Web Delicious! 官网介绍说是“凭借简单和美观的完美结合&#xff0c;图像编辑器是一个功能齐全的编辑器&#xff0c;非常适合日常使…

kafka入门(四):消费者

消费者 (Consumer ) 消费者 订阅 Kafka 中的主题 (Topic) &#xff0c;并 拉取消息。 消费者群组&#xff08; Consumer Group&#xff09; 每一个消费者都有一个对应的 消费者群组。 一个群组里的消费者订阅的是同一个主题&#xff0c;每个消费者接收主题的一部分分区的消息…

基于SSM+JSP网上订餐管理系统(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

原来JMeter 分布式执行原理这么简单,为什么没有早点看到呢!

在使用 JMeter 进行性能测试时&#xff0c;如果并发数比较大&#xff08;比如项目需要支持 10000 并发&#xff09;&#xff0c;单台电脑&#xff08;CPU 和内存&#xff09;可能无法支持&#xff0c; 这时可以使用 JMeter 提供的分布式测试的功能&#xff0c;使用多台测试机一…

当初为什么选择计算机-希望一直干下去

还记得当初自己为什么选择计算机&#xff1f; 当初你问我为什么选择计算机&#xff0c;我笑着回答&#xff1a;“因为我梦想成为神奇的码农&#xff01;我想像编织魔法一样编写程序&#xff0c;创造出炫酷的虚拟世界&#xff01;”谁知道&#xff0c;我刚入门的那天&#xff0…

LLMs 应用程序的构建利器:LangChain 助您驰骋 AI 世界 | 开源日报 No.100

langchain-ai/langchain Stars: 67.9k License: MIT LangChain 是一个旨在通过组合性来构建 LLMs 应用程序的库。它可以帮助开发者快速将 LangChain 应用程序部署到生产环境&#xff0c;同时提供了统一的开发平台&#xff0c;用于构建、测试和监控 LLM 应用程序。该项目主要功…

Bypass open_basedir

讲解 open_basedir是php.ini中的一个配置选项&#xff0c;可用于将用户访问文件的活动范围限制在指定的区域。 假设open_basedir/var/www/html/web1/:/tmp/&#xff0c;那么通过web1访问服务器的用户就无法获取服务器上除了/var/www/html/web1/和/tmp/这两个目录以外的文件。…
最新文章