写在最前:
计算机最擅长计算二进制,是因为很多硬件都是二进制的,就好比人最擅长十进制,因为人有十根手指。
最本质的二进制计算规则都是在补码上进行的,关于原反补的计算简单来说
具体在https://blog.csdn.net/weixin_71138261/article/details/126054557?spm=1001.2014.3001.5501 这篇我的博客里面
目录
1.首先来讲无论整数还是浮点数的存储规则
众所周知,创建变量的本质就是在内存中开辟空间,变量就是用来存放数据的,就好比饭菜要用容器盛装
在把数据放到空间之前,首先要把十进制转换成二进制,究竟写成多少个比特位的形式还是以32个最好,但不是必须,因为数据是多少个字节无所谓,他现在只是一个数字而已,就好比我有100个钱,没有说人民币还是美金一样。
但是一旦补码准备好要放入内存就要根据变量类型来选择最多能放入多少个字节
存:
int a=10;
比如这里
数据10的二进制该怎么转换?
十进制二进制相互转换的小技巧:
第一步 把要转换的数字写成二的次幂的和 :10=8+2
第二步 二的几次幂就对应1后几个0 如果有的位被修改成1也没关系,同样也算一位
8=2^3——>1000, 2=2^1——>10
第三步 在二进制的一串0上,从低位开始数0,改成1
00000000 00000000 00000000 00000000 (以32个比特位为例)
00000000 00000000 00000000 00001010 (原码,但是原反补相同)
所以10的补码准备完毕
现在放入内存空间
2.整型
int a为10准备了4个字节32比特位的空间,如果刚才你写的比特位数不够,前面补充0
然后看是否是signed(不特殊写默认是),是就在符号位对应修改,不是就全补0
char b = -1
//b:10000001
int a = -10
//a:10000000 00000000 00000000 00001010
unsigned char c=-5
//c:00000101
当不同类型相互转换的时候会发生整型截断
int main()
{
int a = -10; //11111111 11111111 11111111 11110101
char b = (char)a; //强制截断从低权值位开始 变成111110101
printf("%u", b);//无符号整型打印,所有位都是数值位
}
最后结果根据和计算器算都是正确的
如果对隐式转换和整形提升还不清楚可以看我的这篇文章
https://blog.csdn.net/weixin_71138261/article/details/126071887?spm=1001.2014.3001.5501
这一部分
3.浮点型
浮点型的规则和整型完全不同
根据IEEE 754 规则 任何一个浮点数都可以分为3部分:(-1)^S*M*2^E
S的值是0 / 1如果是正数就是0,负数是1
M*2^E是科学计数法,1<=M<2
比如 5.5——>对应二进制101.1
原因如下
1 1 1 . 1 1 1
2^2 2^1 2^ 0 . 2^-1 2^-2 2^-3
所以101.1=(-1)^0 * 1.011 * 2^2
所以S=0,M=1.011 ,E=2
对应在内存中
float 单精度浮点数4字节
double 双精度浮点数 8字节
【注】:规定特别要求
M 为了可以多存储一个小数位,由于M一定比1大比2小,所以规定计算机默认储存整数位的1,而M只保存小数点之后
E是无符号整型
如果E是8个比特位,范围是0~255,如果是11比特位,范围是0~2047
但是科学计数法是可以有负数的 ,为了规避这个个问题,放入内存时E的真实值必须加上127/1023这两个中间数,8位+127
比如2^10(float),E的真实值是10+127
E全为0
此时浮点数的指数=1-127/1-1023
有效数字M不再加上1,而是还原真实的小数,为了表示+-0和很接近0的小数
E全为1
此时有效数字M全是1,表示正负无穷(因为正负号取决于S和M E无关)
注意!!!
我们会注意到,在用科学计数法表示的时候。2^(-1)= 0.5 , 2^(-2)=0.25 ,2^(-3)=0.125
所以其实这种二次幂的表示方法精度不如0.1 0.0000001之类的准确
所以当一个小数并不能直接用二次幂完美表示的时候,会造成精度丢失
精度丢失不是指这个小数一味地变小,也可能用上面理论表示出来的值永远比真实值大
理论结束,会了吗?来看一下这道练习题吧
int main()
{
int n = 9;
float* p =(float*) & n;
printf("%f\n", *p);
*p = 9.0;
printf("%d\n",n);
}
一句话总结:
存:字面数据转补码,放入空间中,符号位取决于数据本身有无符号和变量类型无关
去:先看变量类型 signed确定原反补,unsigned直接存,所有比特位都是数值位
创作不易,感谢观看