补码

一、  引言

+0的原码是00 00 00 00;反码是 00 00 00 00;补码是 00 00 00 00;

-0的原码是80 00 00 00;反码是 FF FF FF FF;补码是 00 00 00 00;

补码表示时,+0和-0是相同的,符合正常认知。

二、  解释

2.1、  基础

由此引出计算机中补码的表示规则:正数和零暂不讨论,需要额外注意负数的转换规则。

对于负数进行探讨:

原码 -> 补码  符号位不变,按位取反后+1;

补码 -> 原码  符号位不变,-1后按位取反;

以8位二进制来表示有符号数为例,-128的补码是0x10,按照补码转换成原码的规则,没有办法保证在符号位不变的前提下,得出原码。所以我们得到一个结论:

最小负数只有补码,不存在原码和反码

2.2、  补充

容易与单目运算符~(取反运算符)和-(求补运算符)混淆。下面再举一个例子,对于4位二进制表示的有符号数:

x = -4;(运算时都是以补码的形式参与运算)。

其原码为1100;反码为1011;补码为1100;

如果对x进行求补运算(每一位取反再+1),-x = ~x + 1;即0011+0001=0100(4)。

从上述例子我们可以看到:x的补码是1100;对x进行求补的结果是0100,这两者是不一样的。

2.3、  实例 

int i=-2147483648;

(k为二进制整数可表示的状态有2^k种。负数有2^(k-1)个,正数和0共有2^(k-1)个。int类型占4个字节,负数有2^31个,最小负数就是-2^31=-2147483648。)

i 的补码为80 00 00 00;-1的补码为ff ff ff ff;

-i-1的结果是 ???(-i)+(-1) => i的求补结果和1的求补结果相加;

-i = ~i+1  =>  7f ff ff ff + 00 00 00 01 = 80 00 00 00;

-1 = ~1+1  =>  ff ff ff fe + 00 00 00 01 = ff ff ff ff;

相加为7f ff ff ff = 2147483647。

2.4、  代码验证

#include<stdio.h>
#define INT_MIN     (-2147483647 - 1) 
int main()
{
	int i = INT_MIN;
	printf("%d", -i - 1);
	return 0;
}

 说明:代码中-2147483648要以宏的形式间接给出的原因参见errorC4146: 一元负运算符应用于无符号类型,结果仍为无符号类型

运行结果

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页