图文并茂
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 0;
printf("%d\n", ~a);
return 0;
}
前言:
1,关于第一行代码我要解释一下,这行代码是为了调用scanf函数,虽然说这里用不到,但我已经设定成默认了。
2, 图中的~a是二进制取反,即1变0,0变1。
3,计算机只能识别二进制数,为了简化运算,用了原码,补码,反码的来存储。0是一个字节,而一个字节对应八个比特位。那么也就是32个比特位,可以存储32个二进制数。运行程序后结果是-1。
正题
1原码:在二进制最高位前添加1或0来让计算机识别正负数。添加的1或0叫做符号位
二进制的正数最高位前添加0,负数最高位前去掉负号添加1
例如二进制数110 ——0110
-110 ——1110
由上可以得出正数前加0,负数前的符号用1来替换。
2 先说正数(符号位为了醒目已用红色注明)
正数的原码,反码,补码均一致。
二进制数110——0110——0110——0110
原码 ——反码——补码
3.负数
运算规则负数——最高位前添加1得到原码——符号位不变,其余求反得到反码—加1得到补码
二进制数-110——1110——1001——1010(由1001加1得1010)
原码——反码——补码
4,回到代码,由于负数在计算机储存的是补码因此~a得到是补码(运算过程:
00000000000000000000000000000000 [这一串零是前面的32个比特位上的]变为
11111111111111111111111111111111[这个是补码])
现在来进行逆向运算,因为printf打印的是原码。因为符号位是1,所以是负数。
补码减一——得到反码——符号位不变,其余求反得到原码
11111111111111111111111111111111(补码)
11111111111111111111111111111110(反码)
10000000000000000000000000000001(原码)
最后打印的结果是-1,printf("%d\n",~a)因为这里是%d即打印十进制数的意思。
二进制数