实数的浮点数表示方法
C语言中浮点数的定义:
单精度浮点数:float,占4个字节
双精度浮点数:double,占8个字节
列如:
float x = 1.732f;
double y =3.1415926;
浮点数内存存储结构:科学计数法
目前C/C++编译器标准都遵照IEEE制定的浮点数表示法来表示实数。即二进制中的科学计数法。
科学计数法表示实数
十进制:12735=1.2735*10^4
二进制:
1011.01=1.01101*2^3,1.01101为尾数,3为指数,0为符号位
-0.010101=-1.0101*2^-2, 1.0101为尾数,-2为尾数,1为符号位
在IEEE标准中,浮点数是将特定长度的连续字节(4个字节或者8个字节)的所有二进制位(32位和64位)分割为特定宽度的三个域:
符号域:S,占1位,正数为0,负数为1
阶码域:E,占8位或者11位,E=e+127(float)or e +1023(double),指数e 有正负即有符号数,但阶码为正即无符号数,所以将e加个127或者1023作为偏移,方便指数的比较。
尾数域:M,占23位或者52位,1.01101,但整数部分的1是默认的,可以不用存储
计算浮点数的存储方式,只需要依次求出1位的符号位,8位或11位的阶码,以及23位或者52位的尾数即可。
浮点数的存储不要与整数的编码和存储混淆了
float单精度实数的存储结构:
s(31) | E(阶码,30~23,共8位) | M(尾数,22~0,共23位) |
---|
double双精度的存储结构:
S(63) | E(阶码,52~62,共11位) | M(尾数,51~0,共52位) |
---|
给出一个浮点数,计算对应的二进制
比如给定一个浮点数,7.25,如何计算它对应的单精度和双精度的二进制呢?
1、十进制浮点数7.25对应的二进制为:111.01
2、用二进制的科学计数法为:1.1101*2^2
3、按照浮点数的存储结构,得出符号位为:0,表示正数
4、阶码(指数+127/1023)E单精度为
2+127=129,双精度为2+1023=1025;
5、小数部分M为:1101.(单精度23位,双精度52位,余下的补0,即单精度补19个0,双精度补48个0)
6、所以,7.25的单精度和双精度表示为:
单精度的二进制位为:0 10000001 1101 0000000000000000000
双精度的二进制位为:0 10000000001 000000000000000000000000000000000000000000000000
先在程序里下断点,F5 调试程序,然后查看把变量的地址打印出来的值,然后,调出菜单的debug–>windows–>memory窗口,输入变量的地址,右键内存窗口,选择hexamdemcimal dispay和8-byte Integer就可以查看了。
当然,学了位运算之后,也可以自己写程序,把每个二进制位打印出来。
浮点数阶码的问题
float单精度实数的存储结构:
s(31) | E(阶码,30~23,共8位) | M(尾数,22~0,共23位) |
---|
double双精度的存储结构:
S(63) | E(阶码,52~62,共11位) | M(尾数,51~0,共52位) |
---|
Float:E= e+127 or e = E -127
Double:E = e+1023 or e = E-1023
阶码E为了方便比较,为无符号数,单精度8位,范围1~254,双精度11位,范围1~1026,表示了一个规格化的非零浮点数。真正的指数e范围为(-127) -126~+127和(-1023)-1022~+1023:
阶码全0,尾数全0,表示0;
阶码全1,尾数全0,表示正无穷或负无穷:
阶码全1与非0尾数一起给出NaN(not a number)–非数。
当阶码E为全0且尾数M也为全0时,表示的真值为零,结合符号位S为0或1,有正零和负零之分。当阶码E为全1且尾数M也为全0时,表示的真值为无穷大(∞),结合符号位S为0或1,有正无穷和负无穷之分。这样,在32位浮点数表示中,要除去E用全0和全1(255)表示零和无穷大的特殊情况,因此,阶码E的取值范围变为1~254,指数的偏移量不选128而选127,这样真正的指数值e为-126~+127,因此,数的绝对值的范围是2-126~2127约等于10-38~1038。