CSAPP学习记录-IEEE浮点表示

article/2025/6/10 4:51:02

使用二进制定点表示浮点数十分麻烦,且由于有些浮点数的二进制不能精确表示,只能添加小数位数不断近似,使得位数开销极大。20世纪70年代已经有一些计算机厂家推出了自己的浮点数表示标准,但并不统一,于是在1985年IEEE 742标准被提出,作为目前国际浮点数的表示标准。

IEEE 742标准规定了一个浮点数表示公式: V = ( − 1 ) s ∗ M ∗ 2 E V = (-1)^s * M * 2^E V=(1)sM2E

  • 怎么理解这个公式?

    其实这里有一个知识点:浮点数是用科学计数法来表示的。

    比如十进制数25.125

    25.12 5 ( D ) = 11001.00 1 B = 1.1001001 ∗ 2 4 25.125_{(D)} = 11001.001_{B} = 1.1001001 * 2^4 25.125(D)=11001.001B=1.100100124

    你也可以把它表示成 0.11001001 ∗ 2 5 0.11001001 * 2^5 0.1100100125, 11.001001 ∗ 2 3 11.001001 * 2^3 11.00100123, 110.01001 ∗ 2 2 110.01001 * 2^2 110.0100122, 11100100.1 ∗ 2 − 3 11100100.1 * 2^{-3} 11100100.123等等,实际上浮点数的得名也是源自于它的点位漂浮不定的情况,在实际应用中我们采用IEEE 标准,用科学计数法统一表示这些浮点数。

    回头看公式,其中V(Value)表示浮点数的十进制值;

    S(Sign)符号位表示浮点数的正符号,取1为负,0为正;上例显然是正数, S = 0。

    注意,面对这个符号位要摆脱之前整数补码取反加1求负的思想,实际上求浮点数的负值只要偏转一个符号位就行了。

    M(Mantissa)表示尾数,表示 二进制浮点数 科学计数法表示形式 下的小数部分; 上例中M = 1.1001001

    E (Exponent) 表示阶码,是一个有符号数,表示 二进制浮点数 科学计数法表示形式 的2次幂的值,上例中 E = 4

  • 怎么把数装进计算机的二进制位?

    ​ IEEE 提供了浮点数的32位和64位表示形式:

    image-20211029165937801

    这里除了符号位外又看到两个变量exp 和 frac 。

    这两个参数的作用是什么?这里又要开始讲IEEE标准,制定IEEE标准的这帮人根据exp的值分了三类情况:规格化,非规格化,特殊值情况,我们先主讲规格化的情况。

    • 规格化

      即exp的位模式既不全为0也不全为1的情况,该情况下IEEE二进制数对应到科学计数法表示要通过如下公式:

      E = e x p − b i a s E = exp - bias E=expbias

      M = 1 + f r a c M = 1 + frac M=1+frac

      exp是exponent,即指数,注意别和阶码E混淆,exp是一个无符号整数,而E是有符号整数;

      frac是fraction, 即M去掉整数部分后的小数字段, 注意规格化表示下尾数的第一位一定是1,正如科学计数法下非0数表示的第一位一定非0的情况。

      其中bias 是一个偏置值,和之前2.3用于保证整数向0舍入的bias不一样,这个bias是用于浮点数计算时能对齐两数的阶码使用的。这一部分我并不是了解的很清楚,目前要记住E是一个移码,参考:

      ​ 为什么要用移码来表示阶码(指数)呢?

      bias 的取值是 b i a s = 2 n − 1 − 1 bias = 2^{n-1} - 1 bias=2n11 ,其中 n 是exp的数据位数,单精度下bias 值为 127(n = 8), 双精度下为 1023 (n = 11)。

      单精度情况下,阶码E的有符号表示范围为-127 ~ +128 ,但是-127 和 128 在规格化里是没被用来表示的,原因是在IEEE标准中这两个数分别被用来规定了非规格化和特殊值的情况,也即单精度的规格化阶码exp范围是 00000001 ( − 126 ) − 11111110 ( 127 ) 00000001(-126)-11111110(127) 00000001(126)11111110(127) , 之后讨论。

      注意,看exp不能按正常的二进制转十进制的思维转成十进制,需要减去偏差。

      单精度情况exp和E对照:

      exp(B)exp(D)E
      0000 0000 (非规格化)0-126(非规格化情况E = 1 - bias)
      0000 00011-126
      1111 1110254127
      1111 1111 (特殊值)255

      规格化情况的公式变为:

      V = { ( − 1 ) s ∗ ( 1 + f r a c ) ∗ 2 e x p − 127 , f l o a t ( − 1 ) s ∗ ( 1 + f r a c ) ∗ 2 e x p − 1023 , d o u b l e V = \begin{cases} (-1)^s * (1 + frac)*2^{exp - 127},float\\\ (-1)^s * (1 + frac)*2^{exp - 1023},double\end{cases} V={(1)s(1+frac)2exp127,float (1)s(1+frac)2exp1023,double

      按照规格表示,我们得到了25.125D(即 1.1001001 ∗ 2 4 1.1001001 * 2^4 1.100100124)的单精度表示方法:

      1 ( s , 1 位 ) 1000001 1 ( e x p , 8 位 ) 1001001000000000000000 0 ( f r a , 23 位 ) 1_{(s,1位)} 10000011_{(exp,8位)} 10010010000000000000000_{(fra,23位)} 1(s,1)10000011(exp,8)10010010000000000000000(fra,23)

      注意,在实际的位表示中开头1被省略掉了(即implied leading 1, 隐含的1开头表示),用以获得一个额外的尾数位以提高精度。

      • 非规格化

        阶码域全为0时,表示的值就是非规格化的,非规格数可以用来表示0及其他一些非常小的数,注意+0.0和-0.0在浮点数中是同时存在的,仅有符号位的不同。非规格化中M和E的公式定义为:

        M = f r a c M = frac M=frac

        E = 1 − b i a s E = 1- bias E=1bias

        非规格化的尾数是0开头的,故M代表的就是小数部分,至于E 为什么等于 1-bias会比较费解,其实这里的1是对非规格化数没有隐含的1的补偿,其有益于最大非规格化数到最小规格化数的平滑转变。

        另外,值比较小的规格化的数在更低位数的机器中可能成为非规格化数。我们知道,**增大尾数位有益于提高浮点数的表示精度从而得到更大的规格化值,而增大指数为有益于提高浮点数的表示范围得到更小更精确的规格化值,**我们可以试想下列情况:

        ​ 设阶码位为k, 尾数位为n,偏置量bias

        ​ 32位环境下的某小数0.001953的二进制表示形式为:

        0 ( s , 1 位 ) 0111010 1 ( e x p , 8 位 ) 1111111111110111100111 0 ( f r a , 32 位 ) 0_{(s,1位)}01110101_{(exp,8位)} 11111111111101111001110_{(fra,32位)} 0(s,1)01110101(exp,8)11111111111101111001110(fra,32)

        ​ 其计数表示为 1.1111111111110111100111 ∗ 2 − 10 1.1111111111110111100111 * 2^{-10} 1.1111111111110111100111210

        ​ 放到k = 4,n = 3,bias = 7的机器环境中表示为:

        0 ( s , 1 位 ) 000 0 ( e x p , 4 位 ) 00 1 ( f r a , 3 位 ) 0_{(s,1位)}0000_{(exp,4位)} 001_{(fra,3位)} 0(s,1)0000(exp,4)001(fra,3)

        ​ E = 1 - 7 = -6, M = 0.001 ,故0.001953在该环境下表示为 0.001 ∗ 2 − 6 0.001* 2^{-6} 0.00126

        ​ ( 0.00000000 1 B 0.000000001_{B} 0.000000001B,显然是1/512的近似结果,具体看CSAPP图2-35参考),

        ​ 若要让小数点到达1前,阶码值需要到-9,即规格化表示是 1.0 ∗ 2 − 9 1.0 * 2^{-9} 1.029,可是该环境下的阶码E范围为 -6 ~ 7,显然超出了取值范围,E取最小值也无法满足开头是1的规格化条件,只能表示成非规格形式。

        ​ 另外可见,如果表示的浮点数的计数表示超过了E的最大范围,就会导致溢出,值变为 + ∞ +\infty +。比如上述环境中256.0的计数表示为 1.0 ∗ 2 8 1.0* 2^8 1.028, 用4个指数位已经不够表示了(E = 14(1110) - 7 = 7 < 8(1111)),于是全1溢出。

      • 特殊值

        ​ 特殊值包括正无穷,负无穷和NaN(即不是一个数,Not a Number), 在阶码全为1的时候出现,其中当小数位全为0时,s=1表示负无穷,s=0表示正无穷,如果小数位不全为数就是NaN, 它们的用处是用于表示未初始化的数据,比较少见,这里不再详谈。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ssuzmmJn-1641887708855)(C:/Users/hw/AppData/Roaming/Typora/typora-user-images/image-20211029235949624.png)]

      参考:

      http://kaito-kidd.com/2018/08/08/computer-system-float-point/

      南京大学 计算机系统基础(一)主讲:袁春风老师

  • 2.4.4 舍入

    浮点数有4种舍入方式:向上舍入(往数轴值高方向舍入),向下舍入(往数轴值低方向舍入)向0舍入,向偶数舍入。

    前三种不难理解,最广泛的使用是向偶数舍入:对浮点数x,如果该数不在两数的中间值时,按就近原则舍入;如果正好在中心值,则要保证舍入后的最低有效位是偶数。比如:

    ​ 对1 < 1.5 < 2, 2 < 2.5 < 3, 1.5和2.5会分别向上舍入,向下舍入为2。

    这种舍入特性的优点是,对于求一组数据的平均值时,如果采用向上舍入求平均值会导致测值偏高,如果采用向下舍入求平均值会导致测值偏低,向偶数舍入使得数的舍入有前50%的情况为向上舍入,50%的情况为向下舍入,测值误差最小。

  • 2.4.5 浮点运算

    浮点运算不具有结合性和分配性,而且由于其舍入的特性导致很多诡异的结果,比如(3.14+1e20)- 1e20 会等于 0.0 而不是3.14,计算时把3.14舍去了。

  • 2.4.6 C语言中的浮点数

    C语言中的浮点数采用向偶数舍入的方式。

    值类型从int转换到float,可能被舍入

    值类型从int或者float转换到double, 属于向上扩展,精度不变。

    值从double转到float, 如果值超出了float的范围会溢出。

    值类型从double和float转换到int,会被向0舍入,而且有可能溢出。例如当int x = 1e10(2147483637,即 T m a x T_{max} Tmax时,转换成float能保存精度,但转换回int时会出现不确定舍入值的现象,C语言规定出现此现象作溢出处理,最后打印的值会变为-2147483638。

扩展参考

https://www.atjiang.com/categories/#CSAPP3

C中int8_t、int16_t、int32_t、int64_t、uint8_t、size_t、ssize_t区别

[原码、反码、补码,计算机中负数的表示](


http://chatgpt.dhexx.cn/article/L0vhnKHp.shtml

相关文章

聊一聊 IEEE754 标准(里面涉及浮点数精度丢失问题)

一、什么是 IEEE754 标准 IEEE 二进制浮点数算术标准&#xff08;IEEE 754&#xff09;是 20 世纪 80 年代以来最广泛使用的浮点数运算标准&#xff0c;为许多 CPU 与浮点运算器所采用。IEEE754 标准提供了如何在计算机内存中&#xff0c;以二进制的方式存储十进制浮点数的具体…

【算法】解析IEEE 754 标准

目录结构&#xff1a; contents structure [-] 浮点数的存储过程 次正规数&#xff08;Denormalized Number&#xff09;零&#xff08;zero&#xff09;非数值&#xff08;NaN&#xff09;无穷大&#xff08;infinity&#xff09;除数为0.0会发生什么浮点数的范围浮点数的精度…

如何深刻理解IEEE浮点数的表示(IEEE floating-point representation)

引言 大家都知道&#xff0c;可以在计算机处理器直接运行的是由0,1构成的机器代码(machine code)&#xff0c;本文将介绍浮点数(floating-point number )在机器码中是如何被编码表示的。 整数(integer)是如何被编码的呢&#xff1f;小伙伴们应该听过补码&#xff0c;原码&…

【论文学习】7、ieee802.11ah中基于深度学习的载波频偏估计

摘要 基于ieee802.11标准的Wi-Fi系统是最流行的无线接口&#xff0c;它采用先听后讲&#xff08;LBT&#xff09;的方式进行信道接入。大多数基于LBT的系统的显著特征是&#xff0c;发射机使用在数据之前的前导码来允许接收机执行分组检测和载波频率偏移&#xff08;CFO&#…

计算机中的小数 IEEE754

计算机中的小数 IEEE754 进制计数系统 在基数b的位置记数系统(其中b是一个正自然数&#xff0c;叫做基数)&#xff0c;b个基本符号(或者叫数字)对应于包括0的最小b个自然数。 要产生其他的数&#xff0c;符号在数中的位置要被用到。最后一位的符号用它本身的值&#xff0c;向…

计算机组成原理:IEEE754标准中,为什么指数真值e变成阶码加上的偏移值是127不是128?

1.浮点数在计算机里的存储方式 以32位为例,短浮点型float,按照按照 IEEE754 标准,在计算机里的存储格式如下 数符S&#xff1a;表示浮点数的符号&#xff0c;占1位&#xff0c;0—正数、1—负数&#xff1b; 尾数M&#xff1a;23位&#xff0c;原码纯小数表示&#xff0c;小数…

ieee sci 期刊 写作经验 分享 博士发展阶段

0. 前言 本文仅记录最近我在论文写作中遇到的问题&#xff08;感谢老师、师兄的用心指导&#xff09;&#xff0c;仅仅是我的个人分享&#xff0c;不适用于所有人。 1. introduction - 如何切入自己的工作&#xff1f; 1.1 不要没事找事 例子&#xff1a; 比如你做的是目标…

谈谈论文的发表(电光与控制,IEEE ACCESS)

前言 目前&#xff0c;科研任务差不多告一段落&#xff0c;总结一下发表论文的经验以及经历。 2021年3月&#xff0c;录用IEEE ACCESS一篇&#xff0c;本来老师想让投IEEE trans系列&#xff0c;但是工作的深度差一点&#xff0c;并且没有很好的实例论证&#xff0c;只有仿真&…

IEEE 754标准

普通规则下: 移码: 补码的基础上将符号位取反。注意:移码只能用于表示整数 移码的定义: 移码 真值 偏置值(确定移码&#xff0c;首先要确定偏置值) 偏置值一般取2^n-1&#xff0c;此时移码 补码符号位取反 IEEE 754规则下&#xff1a; 偏置值 2^n-1 - 1 相当于将普通规…

IEEE 754浮点数工业标准

文章目录 浮点数概述浮点数的格式IEEE 754标准规定的浮点数的格式IEEE 754偏移量与指数范围问题IEEE 754中浮点数值的三种情况&#xff1a;1. 规格化的浮点数的值2. 非规格化的值3. 特殊值 Java中的浮点数类型 浮点数概述 浮点数&#xff0c;是属于有理数中某特定子集的数的数字…

SPSS Modeler导入excel文件时出现“无法读取文件列名”解决方法

SPSS Modeler导入excel文件时出现“无法读取文件列名”解决方法 经过本人多次尝试&#xff0c;终于发现了原因 原因是&#xff1a;excel文件在后台打开了&#xff0c;因此spss modeler读取不了 解决方法&#xff1a;关闭正在打开的该excel文件&#xff0c;再读取即可 如果解决了…

SPSS Modeler 数据导入操作

1、导入文本文件 数据选项卡&#xff0c;主要是指定所读取数据的基本类型&#xff0c;通常无需修改&#xff0c;若需修改要先在覆盖那里打钩&#xff0c;然后下拉存储框进行修改 过滤选项卡是选择读取数据时读取哪些数据&#xff0c;同时可以修改变量名。 类型选项卡是指定读取…

SPSS导入excel文件时,保留4位小数点

SPSS导入excel文件时&#xff0c;保留4位小数点 SPSS导入excel文件时&#xff0c;会只保留整数部分&#xff0c;而小数点部分的数据不显示&#xff0c;如下图&#xff1a; 我尝试在SPSS的变量视图里将小数点位数改成4位&#xff0c;如图&#xff0c;但是导入数据后&#xff0c…

SPSS for Mac导入Excel表格找不到文件、以及“文件受密码保护”报错问题的解决办法

SPSS版本25&#xff0c;在导入Excel文件时显示不出来&#xff0c;需要移动到磁盘-用户-apple里面&#xff0c;我这里是我自己的用户名&#xff0c;移进去就可以看到了 之后可以用导入文件打开&#xff0c;也可以直接拖到数据视图&#xff0c;但是我这边又出现了一个小问题 出现…

SPSS数据抽取

SPSS数据抽取 数据抽取一般分为两类&#xff1a;字段拆分和随机抽样 字段拆分 数据抽取&#xff0c;也称为数据拆分&#xff0c;是只保留原数据表中的某些字段、记录的部分信息&#xff0c;形成一个新字段、新记录。 在spss中导入我们需要的数据&#xff0c;变量主要包含如…

利用SPSS做数据分析②之数据处理1

SPSS数据处理有六个步骤&#xff0c;分别是&#xff1a; 数据导入数据清洗数据抽取数据合并数据分组数据标准化 数据处理是根据数据分析的目的&#xff0c;将收集到的数据&#xff0c;用适当的处理方法进行加工、整理&#xff0c;形成适合数据分析的要求样式&#xff0c;它是数…

SPSS怎么筛选无效数据

我们在用IBM SPSS进行数据分析的时候&#xff0c;经常会遇见这样一种情形&#xff0c;想把不符合自己分析要求的数据全部筛掉。我们把这些要筛掉的数据叫作无效数据&#xff0c;无效数据不筛选掉不但会降低分析的效率&#xff0c;而且会影响最终结果的准确性。 要想提高准确性…

SPSS学习笔记

什么都写 插入个案&#xff1a;指一行 插入变量&#xff1a;指一列 设置 语言 编辑->选项 语言中可以选择输出的语言和界面的语言 变量定义 左下角切换到变量视图&#xff0c;可以修改变量的属性 1.类型可选&#xff0c;注意会影响到后面测量中的选项&#xff0c;如…

SPSS数据插补方法

问题&#xff1a;ArcGIS多值提取至点的数据有很多缺失值 这是对多个区域分区统计后的结果&#xff0c;由于ET的质量不高&#xff0c;所以有很多缺失值 那么&#xff0c;怎样才能将这些值进行插补成我们认为可靠的格式呢&#xff1f; 第一步-将arcgis多值提取至点的数据整理成…

python数据导入spss_spss-数据抽取-拆分与合并

数据抽取也成为数据拆分&#xff0c;是指保留、抽取原数据表中某些字段、记录的部分信息&#xff0c;形成一个新字段、新纪录。分为&#xff1a;字段拆分和随机抽样两种方法。 一&#xff1a;字段拆分 如何提取“身份证号码”字段。身份证号码里面包含了许多信息&#xff0c;…