反码与补码都用于表示有符号数。 反码的定义如下:
补码的定义如下:
从定义可以看到,无论是反码还是补码,负数的最高有效位总为1。以占2个字节的short类型为例,用反码表示时有:
最小值: 1000 0000 0000 0000, 即-32767 最大值: 0111 1111 1111 1111,
即32767 可以看到最大和最小值是对称的,而反码能表示的16位数据一共有种,显然是一个偶数,这意味着这样的编码方式有两个0,分别是0000
0000 0000 0000和1111 1111 1111
1111。为了解决这种问题,可以使用补码,补码只有一个零,在反码中表示0的1111
1111 1111
1111在补码中表示-1,总体上补码相当于将反码的负数部分向负半轴方向平移了一位,其最小值1000
0000 0000 0000表示-32768. 例子
可以看到,反码正如其名,只需将原正数数按位取反即可得到其相反数。而补码因为最高位的权重比正数最大值多了一,在按位取反的基础上需要在最低位再加上一来抵消偏移量才能得到原数的相反数。对w位的二进制正数x,需要用来计算其补码。
测试中用到代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include <stdio.h> #include <limits.h> #include "bitctrl.h" int main(int argc, const char \* argv\[\]) { int a = -13; bitsshow(&a); a = 13; bitsshow(&a); return 0; }
#ifndef bitctrl\_h #define bitctrl\_h #define INT\_LEN 32 #define SHORT\_LEN 16 char bitview(int \*, int); void bitchange(int \*, int, char); void bitsshow(int \*); char bitview(int \*src, int pos) { if (pos <= 4) { return \*((char \*)src + pos); } else { printf("Wrong input"); return -1; } } void bitchange(int \*src, int pos, char data) { if (pos <= 4) { \*((char \*)src + pos) = data; } else { printf("Wrong input"); } } void bitsshow(int \*src) { int i = 0; int mask\[INT\_LEN\] = {}; for ( ; i <= INT\_LEN - 1; (\*src) >>= 1, i++) { mask\[i\] = \*src & ~(~(unsigned int)0 << 1); } i--; for ( ; i >= 0; --i) { printf("%d", mask\[i\]); if (i % 4 == 0) printf(" "); } printf("\n"); } #endif /\* bitctrl\_h \*/
|
这里有在线编码转换的网站。