C语言中float的范围到底是多少?

对于float浮点数范围,大部分网站上写的都是,这一看连0都没有,一个基本数据类型连0都表示不了不太合适吧家人们,

image

但别急,实际上是可以表示0的, 而且可表示的范围比上面还要大一丢丢,不知道为什么教科书都是上面的范围

首先,浮点数的表示方法我们都知道

是 1 符号位 + 8 指数位(阶位) + 23 尾数位(小数位) 结合而成,

v2-5740aca0863aa2ba1990026e43769ae6_1440w

 

让我们手动计算浮点数二进制表示,比如425.0这个数, 

先把整数小数分别转成二进制(整数除2取余,小数乘2取整,自行了解),

得到其二进制表示 110101001.0 = 110101001.0*2^0,再用二进制的科学计数法表示就是 1.10101001*2^8,至此,小数位+指数位我们都有了

那应该很简单,把小数位+指数8 往里填不就是了?

但是NO,指数位有额外的规则,IEEE规定要用移码的方式去填充(目的是为了方便比较大小,涉及到数电,这里不展开),偏移量是+127,也就是指数位你要实际上填要 8 + 127 = 135  = 10000111

最终你要填的就是

0 + 1000 0111+ 1010100100..0

我们写个程序再打印一下425.0浮点数的32位信息,如下

0100 0011 1101 0100 1000 0000 0000 0000

哦确实对得上,那到这里我们确认了浮点数的计算方式

公式如下,S是符号位,M是尾数,E是内存中存储的指数,范围0-255

image

 

1+M中的1 是因为任何一个非0数表示成二进制科学计数法,都是1.xxx,这个1是固定的 ,所以M的23位里没必要单独保存这个1,浪费空间,但是计算时可别忘了, 

那么我们开始计算它的上下限,即最大正值与最小正值(负值就是加个负号而已没区别),

M本质就是23位二进制小数,它的最大值就是1-2^-23,范围 0 ~ (1-2^-23)

E是 0 - 255

那直接M跟E取最大跟最小不就搞定了? 但是NO,IEEE 754又规定了如下特殊情况(原因可以自行了解,主要为了加强数值计算的健壮性),

image

 E = 255 跟 E = 0 时都有特殊含义,取不到,

那么只考虑规格数的情况下

最大正值, E = 254,M= 1- 2^-23,即 (1 +  (1- 2^-23)) * 2^127 = 2^128 - 2^104 约等于 3.40e+38

最小正值, E = 1, M = 0,     即  (1 + 0) * 2^-126 =  2^-126 约等于 1.17e-38

所以 1.17e-38 ~ 3.40e+38 就是规格数的范围,也就是教科书上给出的范围,同时,C语言<float.h>中定义的FLT_MIN 是1.17e-38

非规格数 最大值 ,E= 0,M= 1- 2^-23,且指数固定为-126,    即 (0+(1- 2^-23)) * 2^-126 = 2^-126 - 2^-149 约等于1.17e-38

非规格数 最小值,E= 0,注意M最小只能取2^-23,取0就表示0了,     即 (0+ (2^-23)) * 2^-126  = 2^-149 约等于 1.40e-45

1.40e-45 ~ 1.17e-38,这是非规格数的范围

搞定~

 

posted @ 2026-03-20 00:07  白琉璃  阅读(72)  评论(0)    收藏  举报