c/c++开发分享C++浮点型的存储方式详解

服务器sass管理系统

目录一、ieee浮点标准ieee 754对有效数字m和指数e的规定。浮点型及其存储方式有些时候需要变量能存储带小数点的数,或者能存储极大数或极小数。这类数可以用浮点(因小数点是“浮动的”而得名)格式进

目录
    • 一、ieee浮点标准
    • ieee 754对有效数字m和指数e的规定。

      浮点型及其存储方式

      有些时候需要变量能存储带小数点的数,或者能存储极大数或极小数。这类数可以用浮点(因小数点是“浮动的”而得名)格式进行存储。c语言提供了3种浮点类型,对应三种不同的浮点格式。

      当精度要求不严格时(小数点后少于六位),float类型是很适合的类型。double提供更高的精度, 对绝大多数程序来说够用了。longdouble支持极高精度的要求,很少会用到。

      c标准没有说明float、double和long double类型提供的的精度到底是多少,因为不同计算机可以用不同方法存储浮点数。大多数现代计算机遵循ieee754标准(即iec 60559) 的规范,所以这里也将它作为一个示例。

      一、ieee浮点标准

      由ieee开发的ieee标准提供了两种主要的浮点数格式:单精度(32位) 和双精度(64位)。数值以科学记数法的形式存储,每一个数都由三部分组成:符号、指数和小数。指数部分的位数说明了数值的可能大小程度,而小数部分的位数说明了精度。单精度格式中,指数长度为8位,而小数部分占了23位。因此,单精度数可以表示的最大值大约是3.40×1038,其中精度是6个十进制数字。

      ieee标准还描述了另外两种格式:单扩展精度双扩展精度。标准没有指明这些格式中的位数,但要求单扩展精度类型至少为43位,而双扩展精度类型至少为79位。

      类型 最小值 最大值 精度 备注
      ●float 1.175 49×10-38 3.402 82×1038 小数点后6位 单精度32位
      ●double 2.225 07×10-308 1.797 69×10308 小数点后15位 双精度64位

      上表给出了根据ieee标准实现的浮点类型特征。[表中给出了规范化的最小正值, 非规范化的数可以更小。] long double类型没有显示在此表中, 因为它的长度随着机器的不同而变化,而最常见的大小是80位和128位。

      二、存储方式

      ​ 对于浮点型数据,首先我们需要明白的一点是:浮点数和整型数的编码方式是不一样的,ieee浮点标准采用如下形式来标识一个浮点数。

      v = (-1)s m 2e

      • (-1)s 表示符号位,当s=0时,表示正数,当s=1时,表示负数。
      • m 表示有效数字,是一个二进制小数,其值大于等于1,小于2。
      • 2e 表示指数位。

      C++浮点型的存储方式详解

      下面,我将用float作为例子,double道理也是一样的,只是位数有所不同。

      例如:十进制数:88.8125 —> 二进制为:101 1000.1101

      然后将101 1000.1101化成上述公式m的形式,其范围是[1,2),所以将小数点左移6位,得到1.0110001101×26(这里不懂的话对比十进制,小数点左移一位乘以10,二进制则乘以2)。

      最后得到s = 0、m = 1.0110001101、e = 6,但是事情并没有那么简单,我们接着往下看。

      ieee 754对有效数字m和指数e的规定。

      1、有效数字m:

      1<=m<2,也就是说,m写成1.xxx……的形式,其中xxx……表示小数部分。

      ieee 754规定,在计算机内部保存m时,默认这个数的第一位总是1,因此可以被舍去,只保存小数部分。比如保存1.0110001101时,只保存0110001101,后面的位数补0就可以了,等到读取的时候,再把第一位的1补上去。

      2、指数e:

      首先,e为一个无符号整数(unsigned int)

      如果e为8位,它的取值范围为0~255;如果e为11位,它的取值范围为0~2047。但是,我们知道,科学计数法是可以出现负数的,所以ieee 754规定,存入内存的e是真实值加上一个中间数,对于8位的e,中间数是127,对于11位的e,中间数是1023。比如,26 的e是6,所以保存为32位浮点数时,必须保存为6+127=133,即10000101。

      重点:

      结合上述补充的信息完善例子

      float:

      十进制数:88.8125 二进制为:101 1000.1101 == 1.0110001101×26

      • 符号位:0
      • 指数位:6+127=133 二进制为:1000 0101
      • 小数位:1.0110001101去掉最高位1则为:0110001101

      因此浮点数88.8125的ieee浮点表示为:

      —-0—-1000 0101—-011 0001 1010 0000 0000 0000

      符号位- -指数域- – – – – – – – – – -小数域

      根据指数域不同取值分为一下三种情况: 

      1)e不全为0或不全为1(规格化值)

      这是最常见情况,取出内存中的数时,指数e的计算值减去127(或1023),得到真实值,再将有效数字m前加上第一位的1。

      2)e全为0(非规格化值)

      这时,浮点数的指数e等于1-127(或1-1023)即为真实值,有效数字m不再加上第一位的1,而是还原为0.xxxxxxx的小数。这样做是为了表示正负零,以及接近于0的很小的数字。

      举个例子:编码为如下情形:

      0 0000 0000 000 0000 0000 0000 0000 0001

      即2(-23)×2(-126)=2(-149),转成10进制大约等于1.4×10(-45),这就是单精度所能表达最小的正数了。

      3)e全为1(特殊数值)

      当指数域全为1时属于这种情形。此时,如果小数域全为0且符号域s=0,则表示正无穷,如果小数域全为0且符号域s=1,则表示负无穷。如果小数域不全为0时,浮点数将被解释为nan, 即不是一个数(not a number) 。比如计算负数平方根或处理未初始化数据时。

      总结

      本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注<猴子技术宅>的更多内容!

      需要了解更多c/c++开发分享C++浮点型的存储方式详解,都可以关注C/C++技术分享栏目—猴子技术宅(www.ssfiction.com)

      本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ssfiction.com/c-cyuyankaifa/792785.html

      发表评论

      邮箱地址不会被公开。 必填项已用*标注