C语言:数的保存 原码 反码 补码

                              a=6                                     a=-18
a 的原码就是0000 0000 0000 0110        1000 0000 0001 0010

反码:          0000 0000 0000 0110         1111 1111 1110 1101

补码:          0000 0000 0000 0110         1111 1111 1110 1110


对于正数,它的反码就是其原码(原码和反码相同);
负数的反码是将原码中除符号位以外的所有位(数值位)取反,也就是 0 变成 1,1 变成 0。
对于正数,它的补码就是其原码(原码、反码、补码都相同);负数的补码是其反码加 1。
在计算机内存中,整数一律采用补码的形式来存储。这意味着,当读取整数时还要采用逆向的转换,也就是将补码转换为原码。将补码转换为
原码也很简单:先减去 1,再将数值位取反即可。

#include <stdio.h>
main()
{
int a=6;
int b=-18;
printf("%d %d\n",a,b);
}
int a=6;设置断点,调试,单步运行两步
查看CPU窗口

6 - 18 = 6 + (-18)
= [0000 0000 0000 0110] + [1111 1111 1110 1110]
= [1111 1111 1111 0100]
=  [1111 1111 1111 0011]
= [1000 0000 0000 1100]
= -12

18 - 6 = 18 + (-6)
= [0000 0000 0001 0010] + [1111 1111 1111 1010]
= [1 0000 0000 0000 1100]
= [0000 0000 0000 1100]
= [0000 0000 0000 1100]
= [0000 0000 0000 1100]
= 12

5 - 13 = 5 + (-13)
=  [0000 0000 0000 0101] + [1111 1111 1111 0011]
= [1111 1111 1111 1000]
= [1111 1111 1111 0111]
= [1000 0000 0000 1000]
= -8

13 - 5 = 13 + (-5)
= [0000 0000 0000 1101] + [1111 1111 1111 1011]
= [1 0000 0000 0000 1000] 
= [0000 0000 0000 1000]
= [0000 0000 0000 1000]
= [0000 0000 0000 1000]
= 8

你看,采用补码的形式正好把相差的 1 纠正过来,也没有影响到小数减去大数,这个“补丁”真是巧妙。

小数减去大数,结果为负数,之前(负数从反码转换为补码要加 1)加上的 1,后来(负数从补码转换为反码要减 1)还要减去,正好抵消掉,所以不会受影响。

而大数减去小数,结果为正数,之前(负数从反码转换为补码要加 1)加上的 1,后来(正数的补码和反码相同,从补码转换为反码不用减 1)就没有再减去,不能抵消掉,这就相当于给计算结果多加了一个 1。

C语言使用定点格式存储整数,使用浮点格式存储小数

posted @ 2021-03-11 22:13  myrj  阅读(242)  评论(0编辑  收藏  举报