C++基础-原码、反码及补码
以下内容均以8bit值为例进行叙述。
原码
- 最高位为符号位,0为正,1为负,其余位为数字位
如: 127的原码为0111 1111
-127的原码为1111 1111
反码
- 正数的反码与原码一致;
- 负数的反码是保留负数原码的最高位不变,其余位取反,即最高位始终为1
127的反码为0111 1111
-127的反码为1000 0000
补码
- 正数的补码与原码一致;
- 负数的补码是该数的反码加1(只是表示,不是定义);
127的补码为0111 1111
-127的补码为1000 0001
总结
- 正数的原码、反码、补码相同;
- 计算机中,数值一律使用补码来表示和存储;
关于为什么计算机表示和存储数值要用补码
资料说是为了方便计算机将减法转换为加法,计算机中只有加法运算器,但是为什么使用补码可以进行转换?这一步的意义是什么,以二进制讲解比较抽象,以圆为例进行讲解。
其实补码可以用数学中的补数或相反数类比。
如下图所示圆,原点在圆心,往右为x轴正方向,以圆心为端点的射线与x轴夹角为θ,角度逆时针为负,顺时针为正。
设当前角度∠XOA=30°,要转到∠XOA’=90°,有两种方式:
- 顺时针转300°,即30°-300°=-270°=90°
- 逆时针转60°,即30°+60°=90°
在一个圆中,为什么减300°等于加60°,为什么-270°等于90°,搞清楚了这个问题就知道补码的作用了。
一个圆周360°,即360°是一个循环,最小值是0,最大值是359,再增加1又回到0(360),(对比于8位二进制,最小值为0000 0000,最大值为1111 1111,再增加1又回到0000 0000),抛开符号位(对比于反码不考虑符号位),旋转到同一个位置,逆时针转的度数+顺时针转的度数=359+1(对比于去除符号位,其余各位取反再加1,如0101 1101,取反1010 0010,二者相加再加1:0101 1101+1010 0010 +1 = 10000 0000)。更详细的讲解可参考文末的文章链接。