目录
1.浮点型的存储方式
1.1.浮点型存储方式
(1)float类型在内存中的存储方式:
(2)double类型在内存中的存储方式:
1.2.数值计算表达式
~ S 为符号位 0表示整数,1表示负
~E 在 32 位浮点型中,指数位阶码是 8 个比特位,则可以表示的指数范围为0~255,但是指数有正数也有负数,为了表示 -126 ~127,则对每次存储的指数值加上偏移值,读取时在自动减去127。这样指数位为127时表示实际指数为0,指数位大于127表示正指数,指数位小于127表示负指数。指数位阶码位全为 1 和全为 0 用作特殊情况,剩下阶码取值从 1 到 254,减去偏移值后得到指数取值从 -126 到 127。
~E 在 64 位浮点型中,指数位阶码是 11个比特位,则可以表示的指数范围为0~2047,但是指数有正数也有负数,为了表示 -1022 ~1023,则对每次存储的指数值加上偏移值,读取时在自动减去1023。这样指数位为1023时表示实际指数为0,指数位大于127表示正指数,指数位小于1023表示负指数。指数位阶码位全为 1 和全为 0 用作特殊情况,剩下阶码取值从 1 到 2046,减去偏移值后得到指数取值从 -1022到 1023。
~M 表示科学记数法中的尾数部分,由于正规化的浮点数小数点前总是[ 1 , 2 ),所以尾数位实际上省略了小数点前的1。例如尾数位值为 1001,则代表实际值为 1.1001。
1.3.存储详解
#include<stdio.h>
int main(void)
{
float a = 10.5;
double b = 10.5;
return 0;
}
浮点数10.5转换为二进制为1010.1 利用公式转化1010.1 ==
故符号位 S = 0,指数位 E == 3,尾数位 M == 0101
float类型存入时指数位时加偏移值127,即存入130 (二进制:1000 0010)
0 1000 0010 010 1000 0000 0000 0000 0000
十六进制:0x41280000 double类型存入时指数位时加偏移值1023,即存入1026 (二进制:100 0000 0010)
0 100 0000 0010 0101 00000000 00000000 00000000 00000000 00000000 00000000
十六进制:0x40250000 00000000
用VS,验证变量a的内存存储情况正好为0x 41280000
用VS,验证变量b的内存存储情况正好为0x 40250000 00000000
2.类型强制转换
2.1.指针类型强转
(1)int -----> float
#include<stdio.h>
int main(void)
{
int a = 10;
float* f = (float*)&a;
printf("%f",*f);
return 0;
}
1. 整形数据在内存中以补码的方式存储,变量 a 为整型占4字节,32比特,
且10的补码为 00000000000000000000000000001010 ,
故10在内存中的存储方式如下图
2.程序只对地址进行了类型转换,内存地址内保存的内容保持不变,仍然为整数10,由于float 类型与int 类型在内存中均占32个字节,所以通过 float *类型指针访问32比特内存恰好是变量a所在的32比特,编译器就会按照 float 类型的存储格式解释内存中的值;
此时 S = 0,E = -127, M = 1.000 0000 0000 0000 0000 1010
故
因此程序输出结果为0.000000
(2). float ---> int
#include<stdio.h>
int main(void)
{
float a = 10.5;
int* p = (int*)&a;
printf("%d", *p);
return 0;
}
a 在内存中存储结构如下图:
通过int * 类型指针访问变量a所在的32比特,编译器就会按照int 类型的存储格式解释内存中的值;
因为符号位为0,所以这32bits被解释为整数,即
01000001001010000000000000000000B = 1093140480D
经过vs环境运行,结果与上文分析一致
2.2.变量类型强转
(1).int --->float
#include<stdio.h>
int main(void)
{
int a = 1234567890;
float f = (float)a;
printf("%f", f);
return 0;
}
整型1234567890 的二进制补码为
将int 类型 转换成 float 类型即将a的补码当作浮点数存入内存,如下图
此时S= 0,E= 30 ,M= 1.00100110010110000000101101001
又因为float类型的位数部分只有23bits,故多余部分会被舍弃,只保留23位,第24位为1进1,否则舍去。得到 M = 1.001 0011 0010 1100 0000 0110
S,E,M,按规则存入内存
当float类型数据输出时,得到S= 0,E= 157-127=30,M = 1.001 0011 0010 1100 0000 0110
转化为十进制为1234567936.000000
经过vs运行检验,与理论数据一致
(1).float ---> int
#include<stdio.h>
int main(void)
{
float a = 12.5;
int b = (int)a;
printf("%d", b);
return 0;
}
由前面内容可计算出12.5 在内存中的存储为
强转为int 时将其从内从取出:1010.1 去掉小数部分,将整数部分(1010)存入int型内存单元
故通过%d输出时输出为12