[toc]

二进制原码-补码-反码

  • 数在计算机中是以二进制形式表示的,分为有符号数无符号数

  • 原码、反码、补码都是有符号定点数的表示方法。

  • 一个有符号定点数的最高位为符号位,**0是正,1是副。**

1. 原码就是这个数本身的二进制形式

1
2
3
//例如:
0000001 就是+1
1000001 就是-1   

2. 正数的反码和补码都是和原码相同

1
2
3
4
5
6
7
8
9
//负数的反码是将其原码除符号位之外的各位求反。

[-3]:
源码:[10000011]
反码:[11111100]
//负数的补码是将其原码除符号位之外的各位求反之后在末位再加1
补码:[11111101]

//一个数和它的补码是可逆的

3. 设立补码的原因有两个

  • 第一是为了能让计算机执行减法:[a-b]补=a补+ (-b)补????

  • 第二个原因是为了统正0和负0正零: 00000000 负零: 10000000

    • 这两个数其实都是0,他们的原码却有不同的表示,但是他们的补码是样的, 都是0000000

    • 那么,000000这个补码表示的哪个数的补到呢?其实这是一个规定,这个数表示的是-128  所以n位补码能表示的范围是  -2^(n-1)到2^(n-1)-1  比n位原码能表示的数多一个。

4. 应用实例

  • public static int parseInt(String s, int radix);
  • huffmanCodeBytes[index] = (byte)Integer.parseInt(strByte,2);
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  ///二进制对应的字符串String s = "10101000"
///赫夫曼编码字节数组:return : 168
///经过强转 (byte)168 --> 得到 -88
///我们平时用到Integer.parseInt("123");其实默认是调用了int i =Integer.parseInt("123",10); 其中10代表的默认是10进制
public static int parseInt(String s, int radix) throws NumberFormatException {
/*
* WARNING: This method may be invoked early during VM initialization
* before IntegerCache is initialized. Care must be taken to not use
* the valueOf method.
*/

if (s == null) {
throw new NumberFormatException("null");
}
///public static final int MIN_RADIX = 2;
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}

///public static final int MAX_RADIX = 36;
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
}

int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;

if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s);

if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}

5.总结

在计算机内,定点数有3种表示法:原码、反码和补码

所谓原码就是前面所介绍的二进制定点表示法,即最高位为符号位,“0” 表示正,“1” 表示负,其余位表示数值的大小。

反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。

补码表示法规定:正数的补码与其原码相同:负数的补码是在其反码的求位加1。