整形在内存中的存储
对于正数来说:原码=反码=补码
对于负数来说:最高位为1(表示负数),原码——>反码(最高位不变,其余位取反),反码——>补码(反码最后一位加1=补码)
先看下列代码
#include<stdio.h>
int main(int argv,char *argc[])
{
char a = -1;
unsigned char b = -1;
printf("%d,%d\n",a,b);
return 0;
}
打印结果为:-1,255
整数在计算机中都是以补码的形式存在。
对于char a = -1:
原码:1000 0000 0000 0000 0000 0000 0000 0001
反码:1111 1111 1111 1111 1111 1111 1111 1110
补码:1111 1111 1111 1111 1111 1111 1111 1111
对于char 拿出低八位1111 1111,数据以%d打印,需要提升至32位,对于有符号来说,补的数据按照高位符号位来确定
补完后的补码(根据数据类型来---char a)1111 1111 1111 1111 1111 1111 1111 1111 ----------> 补完后的原码 (根据打印类型来:如果%d,最高位按照类型补,如果%u,原反补一致)1000 0000 0000 0000 0000 0000 0000 0001 --------------->打印-1(存储的是补码,打印的是原码)
对于unsigned char b = -1:
原码:1000 0000 0000 0000 0000 0000 0000 0001
反码:1111 1111 1111 1111 1111 1111 1111 1110
补码:1111 1111 1111 1111 1111 1111 1111 1111
对于unsigned char 拿出低八位1111 1111,数据以%d打印,需要提升至32位,对于无符号来说,高位补0
补完后的补码000 0000 0000 0000 0000 0000 1111 1111(对于无符号来说,即正数,他的原码补码反码都是一致的) --------------->打印255(存储的是补码,打印的是原码)
再看下列代码
#include<stdio.h>
int main(int argv,char *argc[])
{
char a = -128;
printf("%u\n",a);
return 0;
}
打印结果:4294967168
对于char a = -128:
原码:1000 0000 0000 0000 0000 0000 1000 0000
反码:1111 1111 1111 1111 1111 1111 0111 1111
补码:1111 1111 1111 1111 1111 1111 1000 0000
拿出低八位1000 0000 %u是无符号正数打印
补码提升至32位(因为a是有符号类型的,所以需要按照最高位类型补数):1111 1111 1111 1111 1111 1111 1000 0000 (根据%u)---->输出4294967168
浮点型在内存中的存储
之前说的整数,大小可在limits.h中可以查看,而浮点型数据大小范围可以再float.h中查看
先看下列代码:
#include<stdio.h>
#include <arpa/inet.h>
int main(int argv,char *argc[])
{
int a = 5;
float *p = (float*)&a;
printf("a =%d\n",a);
printf("*p =%f\n",*p);
*p = 5.0;
printf("a =%d\n",a);
printf("*p =%f\n",*p);
return 0;
}
输出结果:
整数在强制转换为浮点数的时候数据存储发生了改变
那么浮点型数据是如何进行存储的呢?
举例:单精度浮点数5.5
二进制表示:101.1 ----------5(101) .5(0.5*2 = 1.0刚好就是1 详看:https://jingyan.baidu.com/article/eb9f7b6dc692e9c79264e878.html)
101.1 = (-1)* 0 * 1.011 * 2^2
s=0 M=1.011(实际存贮的只有.011) E=2
对于单精度浮点数 S:1位 E :8位 M:23位
S=0 M=1.011(实际存贮的只有.011) E=2(2+127) 存储值:129 真实值:2
0 1000 0001 011 0000000000000.....(把转换完后小数点后面二进制填上,其余位补0)
读到这,想必大家都知道为什么会输出以上结果了吧。
int a=5
原=反=补 :0000 0000 0000 0000 0000 0000 0000 0101 当我们*p以%f去读取这个补码的时候
E全为0,表示接近于0的很小数字 ,所以*p =0.000000
当按照浮点型存储以后 2+127
5.0 = 101.0 = (-1)*0 * 1.01*2^2 = 01000 0001 0100 0000 0000 0000 0000 000
当我们以%d读取 就变成了 0100 0000 1010 0000 0000 0000 0000 0000 =1084227584