Float的取值范围
Float的存储结构
浮点数在机内用指数型式表示,分解为:
数符,尾数,指数符,指数四部分。
数符占1位二进制,表示数的正负。
指数符占1位二进制,表示指数的正负。
尾数表示浮点数有效数字,0.xxxxxxx,但不存开头的0和点
指数存指数的有效数字。
符号位(1bit) | 指数位(8bit) | 尾数位(23bit) |
1 | 8 | 23 |
IEEE
IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值
一个浮点数 (Value) 中有那些:
也就是浮点数的实际值,等于符号位(sign bit)乘以指数偏移值(exponent bias)再乘以分数值(fraction)。
Float的值是如何计算的
Value=sign*exponent*fraction;
sign是表示符号位的只有正负之分
exponent表示指数偏移值
fraction表示分数
指数偏移值(exponent)
一共有8个bit
第一个字节位符号位也就是判断正负的一个bit
剩下7个可以知道指数偏移值的取值范围为[-127, 128]。
但是,在IEEE 754 有一个标准就是二进制数的表示的方式是
实际值加上固定的偏移值
指数的固定偏移值为2的指数域的次方再减去1,也就是2^8-1
eg:
如果要表示1,则有1 + 127 = 128,用二进制表示即为
0000 0001 + 0111 1111 = 1000 0000
为何使用非规约形式的浮点数
IEEE754-1985标准采用非规约浮点数,用来解决填补绝对值意义下最小规约数与零的距离。
非规约浮点数源于70年代末IEEE浮点数标准化专业技术委员会酝酿浮点数二进制标准时,Intel公司对渐进式下溢出(gradual underflow)的力荐。而当时十分流行的DECVAX机的浮点数表示采用了突然式下溢出(abrupt underflow)。
如果没有渐进式下溢出,那么0与绝对值最小的浮点数之间的距离(gap)将大于相邻的浮点数之间的距离。例如单精度浮点数的绝对值最小的规约浮点数是2-126,绝对值次小的规约浮点数为(1 + 2^-23) * 2^-126,这两个数之间的距离为(1 + 2^-23) * 2^-126 - 2^-126 = 2^-149。而2^-126与0之间的距离为2^-126,如果不采用渐进式下溢出,那么绝对值最小的规约浮点数与0的距离是相邻的小浮点数之间距离的223倍!可以说是非常突然的下溢出到0。
采用了渐进式下溢出后将不会出现这种情况。例如对于单精度浮点数,指数部分实际最小值是(-126),对应的尾数部分从000……000,000……001,000……010,000……011 一直到111……101,111……110,111……111,每两个相邻两小浮点数之间的距离(gap)都是2^-126 * 2^-23 = 2^-149;而0与最近的浮点数(即最小的非规约数)之间的距离也是2^-149。
实际操作
8.25用二进制形式表示为1000.01,表示成二进制的指数形式为1.00001 * 2^3,用科学计数法则表示为1.00001 * 2E3。
因为是正数,所以符号位即最高位为0;
指数位为3 + 127(移位存储) = 130,二进制形式是10000010;
尾数部分00001 = 0000100 00000000 00000000(23位)。
所以8.25在内存中储存为:0 10000010 00001000000000000000000
规约形式的浮点数
如果浮点数中指数部分的编码值在[1, 2^指数域- 2]之间,且在科学表示法的表示方式下,尾数部分最高有效位(即整数字)是1,那么这个浮点数将被称为规约形式的浮点数。“规约”是指用唯一确定的浮点形式去表示一个值。
单精度(32bit)的规约形式浮点数指数偏移值的值域为00000001到11111110,尾数部分则是从000……000(共23个0)到111……111(共23个1)。
求规约数0 00000001 00000000000000000000000所表示的十进制数
分析:
第一个0表示正数;
指数位为1 -127 = -126;
尾数位为1(这个1是隐藏的,别忘了加上)。
所以对应的十进制为2-126 ,这是规约数所能表示的最小的正数。
同理规约数1 00000001 00000000000000000000000表示的是最大的负数为-2^-126。
非规约形式的浮点数
如果浮点数的指数部分的编码值是0,分数部分非零,那么这个浮点数将被称为非规约形式的浮点数。一般是某个数字相当接近零时才会使用非规约型式来表示。IEEE754标准规定:非规约形式的浮点数的指数偏移值比规约形式的浮点数的指数偏移值小1,即非规约的偏移值为126。
例如,最小的规约形式的单精度浮点数的指数部分编码值为1,指数的实际值为-126;而非规约的单精度浮点数的指数域编码值为0,对应的指数实际值也是-126而不是-127。
所有的非规约形式的浮点数的绝对值小于所有的规约浮点数的绝对值;即所有的非规约浮点数比规约浮点数更接近0。
求非规约数0 00000000 00000000000000000000001所表示的十进制
分析:
因为是非规约数,所以指数位是0 -126 = -126,而不是0 - 127 = -127;
非规约数的尾数部分没有隐含的1,所以尾数部分为2^-23;
所以对应的十进制为2^-23 * 2^-126 = 2^-149,这是非规约数所能表示的最小的正数。
同理非规约数所能表示的最大负数为1 00000000 00000000000000000000001= -2^-149。
求非规约数0 00000000 11111111111111111111111所表示的十进制
分析:
因为是非规约数,所以指数位是-126,而不是0 – 127 = -127;
非规约数的尾数部分没有隐含的1,所以尾数部分为2^-1 + 2^-2 + … + 2^-23 = 1 - 2^-23 ≈ 1(但略小于1);
所以对应的十进制数略小于2^-126。
这也是最大的正非规约数,接近但略小于最小的规约数2^-126。
同理最小的负非规约数,接近但略大于最大的规约数-2^-126。
Float的各种极值
类别 | 正负号 | 实际指数 | 有偏移指数 | 指数域 | 尾数域 | 数值 |
零 | 0 | -127 | 0 | 0000 0000 | 000 0000 0000 0000 0000 0000 | 0.0 |
负零 | 1 | -127 | 0 | 0000 0000 | 000 0000 0000 0000 0000 0000 | −0.0 |
1 | 0 | 0 | 127 | 0111 1111 | 000 0000 0000 0000 0000 0000 | 1.0 |
-1 | 1 | 0 | 127 | 0111 1111 | 000 0000 0000 0000 0000 0000 | −1.0 |
最小的非规约数 | * | -127 | 0 | 0000 0000 | 000 0000 0000 0000 0000 0001 | ±2× 2= ±2≈ ±1.4×10 |
中间大小的非规约数 | * | -127 | 0 | 0000 0000 | 100 0000 0000 0000 0000 0000 | ±2× 2= ±2≈ ±5.88×10 |
最大的非规约数 | * | -127 | 0 | 0000 0000 | 111 1111 1111 1111 1111 1111 | ±(1−2) × 2≈ ±1.18×10 |
最小的规约数 | * | -126 | 1 | 0000 0001 | 000 0000 0000 0000 0000 0000 | ±2≈ ±1.18×10 |
最大的规约数 | * | 127 | 254 | 1111 1110 | 111 1111 1111 1111 1111 1111 | ±(2−2) × 2≈ ±3.4×10 |
正无穷 | 0 | 128 | 255 | 1111 1111 | 000 0000 0000 0000 0000 0000 | +∞ |
负无穷 | 1 | 128 | 255 | 1111 1111 | 000 0000 0000 0000 0000 0000 | −∞ |
* | 128 | 255 | 1111 1111 | non zero | NaN |
float类型的规律:
浮点数有三种表现形式:规约形式、非规约形式、三个特殊值。
形式 | 指数 | 小数部分 |
0 | 0 | 0 |
非规约形式 | 0 | 非0 |
规约形式 | 1 ~ 2e - 2 | 任意 |
无穷 | 2e - 1 | 0 |
NaN | 2e - 1 | 非0 |
规约浮点数的尾数大于等于1且小于2。
非规约数尾数部分大于0且小于1。
绝对值最大的非规约数略小于绝对值最小的规约数2-126。
所有的非规约数比所有的规约数更接近于0。
float浮点数可表示的大小为: