在计算机中,表示数值的数字符号只有0和1两个数码,我们规定最高位符号位,并用0表示正数符号,用1表示负数符号。这样,机器中的数值和符号全“数码化”了。
为简化机器中数据的运算操作,人们采用了原码、补码、反码等几种方法对数值位和符号位统一进行编码。
1、原码反码补码表示法
比如C++的整数类型:short,2个字节,16位,最高位0表示正数、1表示负数。
原码表示法
原码表示法是一种简单的机器数表示法,即符号和数值(真值)表示法。
short a = 5; a的原码是 0000 0000 0000 0101
正数使用原码表示法,就是真值本身。
反码表示法
反码的作用就相当于数学中的负数,才可以实现减法与加法运算统一成加法运算。
5 -3 相当于 5 + (-3)
负数的反码,只须对符号位以外各位按位“求反”(0变1,1变0)即可。
short a = -5; a的原码是 1000 0000 0000 0101
a的反码是 1111 1111 1111 1010
负数的原码,最高位是1,真值本身;
负数的反码,最高位是1,真值的其他位取反;
补码表示法
数字 0,既不是正数,也不是负数。+0 和 -0 代表的都是 0。
但是:
它的原码是:0000 0000 0000 0000 (正数表示法)
它的反码是:1111 1111 1111 1111 (负数表示法)
导致:0 这个数字在计算机中的编码就不是唯一的了
用补码表示 0 和 负数,可以避免这个问题,补码也就是打个补丁的意思,专门用于解决这个问题。
负数的补码是符号位为1,数值各位取反(0变为1、1变为0),最低位加 1。用补码表示法,0这个数字在计算机中就是唯一的了。
short a = -5; a的原码是 1000 0000 0000 0101
a的反码是 1111 1111 1111 1010
a的补码是 1111 1111 1111 1011
正数在计算机中用原码表示法,负数和0在计算机中用补码表示法。
#include <iostream>
#include <bitset>
using namespace std;
int main(){
short x = 0b1111111111111011;
cout << x << endl;
cout << "5的二进制:" << bitset<16>(5) << endl;
cout << "-5的二进制:" << bitset<16>(-5) << endl;
return 0;
}
2、原码、反码、补码总结
一个正数:
-
原码、反码、补码的表示形式相同,符号位为 0,数值位是真值本身;
-
[x]原码=[x]反码=[x]补码
一个负数:
-
原码、反码、补码的符号位都为 1
-
数值位原码是真值本身;
-
反码是各位取反;
-
补码是各位取反,最低位加1。[x]补码=[x]反码+1。
-
数字0:
- 原码和反码表示不唯一,而补码表示是唯一的。
3、数的定点和浮点
在计算机中小数点一般有两种表示法:一种是小数点固定在某一位置的定点表示法;另一种是小数点的位置可任意移动的浮点表示法。相应于这两种表示的计算机分别称为定点计算机和浮点计算机。
定点表示法
机器中所有数的小数点位置是固定不变的,因而小数点就不必使用记号表示出来。实际上,小数点可固定在任意一个位置上。
浮点表示法
在数的定点表示法中,由于数的表示范围较窄常常不能满足各种数值问题的需要。为了扩大数的表示范围,方便用户使用,有些计算机常采用浮点表示法。
表示一个浮点数,要用两部分:尾数和阶码。尾数用以表示数的有效数值;阶码用以表示小数点在该数中的位置。
计算机多数情况下采作浮点数表示数值,它与科学计数法相似,把一个二进制数通过移动小数点位置表示成阶码和尾数两部分。