在计算机中,数据存储以补码形式存储,负数的补码为其反码+1,正数的补码不变.
补码存在的意义: 能让符号位直接参与运算,只需要加法器就能运算,简化电路设计
1 - 1 如何实现 ==> 1 + (-1)
1补码与原码相同
0000 0000 0000 0000 0000 0000 0000 0001
-1原码
1000 0000 0000 0000 0000 0000 0000 0001
-1反码(符号位不变)
1111 1111 1111 1111 1111 1111 1111 1110
-1补码
1111 1111 1111 1111 1111 1111 1111 1111
1 + (-1)就为:
0000 0000 0000 0000 0000 0000 0000 0001
1111 1111 1111 1111 1111 1111 1111 1111
结果:左侧溢出
0000 0000 0000 0000 0000 0000 0000 0000
下面结果为什么呢
char a = -128;
printf("%u",a); // %u => unsigned int输出
char 范围 127 / -128
-128在内存中是补码
char => int => unsigned int
1000 0000 补码
1111 1111 1111 1111 1111 1111 1000 0000 转成int,符号位补 1 (负数)
1111 1111 1111 1111 1111 1111 1000 0000 int转化为unsigned int 将符号位理解为数字
结果 : 4294967168
char b = 128;
printf("%u",b);
128超出范围
127内存中
0111 1111 +1 就为128
1000 000 => -128 溢出了
输出结果:4294967168 等同-128
int i = -20;
unsigned int j = 10;
printf("%d",i + j);
-20 补码
1111 1111 1111 1111 1111 1111 1110 1100
10 补码
0000 0000 0000 0000 0000 0000 0000 1010
结果
1111 1111 1111 1111 1111 1111 1111 0110
通过-1取反可知
它的值就为-10
unsigned int i;
for(i = 9; i >= 0; i--)
{
printf("%u\n",i);
}
结果会无限循环
当i= 0时 i–
结果就为
1111 1111 1111 1111 1111 1111 1111 1111
char a[1000];
int i;
for( i = 0; i < 1000; i--)
{
a[i] = -1 - i;
}
printf("%d",strlen(a));//strlen会在数组值等于零时停止
-1-i会溢出char的范围
-1
1111 1111 1111 1111 1111 1111 1111 1111
=> char截断,只剩下后八位1111 1111,只要让最低8位为0就行
当i为 255时
0000 0000 0000 0000 0000 0000 1111 1111
补码
1111 1111 1111 1111 1111 1111 0000 0001
相加后8位为0
那么a[255] == ‘\0’;
0- 254共255个有效元素
strlen 值为255
int n = 9;
float *p = (float*)&n;
printf("%f\n",*p);
结果为 0
浮点数和整数之间的内存存储方式差距很大
123456 => 1.2345610^5科学计数法表示
0000 1001 => 1.0012^3
由国际标准IEEE(电气和电子工程协会)
(-1)^S * M * 2^E
(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
浮点数自带符号位S