补码的使用及整型浮点型在内存中的存储

补码的使用

在计算机中,数据存储以补码形式存储,负数的补码为其反码+1,正数的补码不变.
补码存在的意义: 能让符号位直接参与运算,只需要加法器就能运算,简化电路设计

例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

例2

下面结果为什么呢

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

例3

char b = 128;
printf("%u",b);	

128超出范围
127内存中
0111 1111 +1 就为128
1000 000 => -128 溢出了
输出结果:4294967168 等同-128

例4

int i = -20;
unsigned int j = 10;
printf("%d",i + j);
  1. i + j 要转化成unsigned int 再计算
  2. i + j 的结果还需要再转成 int

-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

例5

unsigned int i;
for(i = 9; i >= 0; i--)
{
	printf("%u\n",i);
}

结果会无限循环
当i= 0时 i–
结果就为
1111 1111 1111 1111 1111 1111 1111 1111

例6

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.001
2^3
由国际标准IEEE(电气和电子工程协会)
(-1)^S * M * 2^E
(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。

浮点数自带符号位S

发布了53 篇原创文章 · 获赞 46 · 访问量 7243

猜你喜欢

转载自blog.csdn.net/new_bee_01/article/details/90271242