准确详解:C/C++ float、double数据类型的表示范围及精度

2023年6月7日10:09:14

本文转载自:https://blog.csdn.net/black_kyatu/article/details/79257346

今天复习C++遇到了float、double数据类型的表示范围及精度问题,花费了一些时间重新梳理了一遍,鉴于网上很多文章写的并不清晰,并且有不少疏漏错误之处,特结合个人理解仔细整理如下。

要弄清楚这个问题,首先要搞清楚浮点数在内存中的存储方式。浮点数,区别于定点数,指的是小数点位不确定的的数据类型,其原理是将一个浮点数a用两个数m(尾数)和e(指数)来表示:a = m × b^e。其中的b为选取的基数。科学计数法就是一种特殊形式的浮点数。

在计算机二进制表示中,浮点数采用2作为基数,规定尾数的范围为1.0~2.0之间。

以float类型为例,根据最广泛采用的IEEE754标准规定,float数据类型长度为32位,其中最高位为符号位,中间8位为指数位,最后23位作为尾数位。

最高位符号位通过0/1来区分正负,0正1负;指数位则规定采用移码的形式存储,这样可以保证指数部分为无符号数,方便比较大小。移码表示法是在数X上增加一个偏移量来定义的,如果机器字长为n,规定偏移量为2(n-1),对于8位补码-128~127,可得到对应的阶码表示为0~255,其中全0和全1分别用来表示0和无穷大,故规定1~254用来表示规范数字,即对应指数范围从-126到127;尾数部分统一规定为1.0-2.0之间,最高位必然为1,故可以省略,所以尾数部分从小数点后算起,最小可以取到1,最大则取到二进制1.1…1(小数点后23位),即取到2-2-23,可近似约等于2。故得到float绝对值的最大值取到2127*(2-2-23)约等于2128=3.4E+38。加上符号之后可得float表示范围为(-3.4E+38)~(3.4E+38)。当然实际是取不到的,开区间。绝对值最小则可以取到2-127*1,即为1.175E-38。

接下来解释精度。由于尾数部分位数是固定的小数点后23位,23位所能表示的最大数是2^23−1=8388607,所以十进制的尾数部分最大数值是8388607,也就是说尾数数值超过这个值之后,float将无法精确表示,所以float最多能表示小于8388607的小数点后7位,但绝对能保证的为6位,也即float的十进制的精度为为6~7位。

double数据类型的推算过程和上述同理,唯一的区别在于尾数由23位扩展到52位,阶码由8位增加到了11位,计算方法不变。所以double的阶码(移码表示)为12046,偏移量为1023,故指数范围为-10221023,得表示范围为(21023*2)~(-21023*2)即为-1.7E+308~1.7E+308,绝对值最小可以取到2-1022,精度则为252-1=4503599627370495,为16位。所以精度最高位16位,一定可以保证15位。

  • 作者:顾缘君兮
  • 原文链接:https://blog.csdn.net/qq_41117896/article/details/108542435
    更新时间:2023年6月7日10:09:14 ,共 1206 字。