计算机中的二进制

  1. 1. 前言
  2. 2. 二进制
  3. 3. 有符号数和无符号数
    1. 3.1. 有符号数
    2. 3.2. 无符号数
    3. 3.3. 栗子
      1. 3.3.1. Java 中 int 类型在计算机类型中的表示方法
      2. 3.3.2. 二进制转换
  4. 4. 原码、反码、补码
    1. 4.1. 有符号数
    2. 4.2. 栗子
      1. 4.2.1. 1+1
      2. 4.2.2. 1-2
  5. 5. JAVA中所有的数字变量都是有符号(正负)的?
  6. 6. 注意点

前言

计算机中存储数据的最小单元为 bit(位),简记为 b ,二进制中的 0、1 便是一个 bit,并且 8bit = 1byte(字节)。

二进制

十进制为逢十进一,而二进制则为逢二进一,二进制使用0和1表示任意数。

有符号数和无符号数

计算机中参与运算的数字可以分为两类:有符号数和无符号数。

有符号数

对于有符号数而言,符号的正、负机器是无法识别的,但由于“正、负”恰好是两种截然不同的状态,如果用“0”表示“正”,用“1”表示“负”,这样符号也被数字化了,并且规定将它放在有效数字的前面,即组成了有符号数。所以,在二进制中使用最高位(第一位)来表示符号,最高位是0,表示正数;最高位是1,表示负数。

无符号数

无符号数是针对二进制来讲的,无符号数的表数范围是非负数。全部二进制均代表数值(所有位都用于表示数的大小),没有符号位。即第一个”0”或”1”不表示正负。

栗子

Java 中 int 类型在计算机类型中的表示方法

  • +1 = 00000000 00000000 00000000 00000001
  • -1 = 10000000 00000000 00000000 00000001

二进制转换

从右到左用二进制的每个数去乘以2的相应次方(次方要从0开始算起)。

二进制转十进制

1
2
3
4
10101
=1*2^4+0*2^3+1*2^2+0*2^1+1*2^0
=16+4+1
=21

十进制转二进制

1
2
3
4
5
6
7
21=
21/2=10.........1
10/2=5..........0
5/2=2...........1
2/2=1...........0
1/2=0...........1
=10101

进制间转换请参考:进制间转换

原码、反码、补码

有符号数

  • 二进制的最高位是符号位:0代表正数,1代表负数
  • 正数的原码,反码,补码都一样
  • 负数的反码等于符号位不变,其他位取反,即1变0,0变1
  • 负数的补码等于反码加1
  • 0的反码和补码都是0
  • 在计算机运算时,都是以补码的方式来运算的

栗子

1+1

  1. 1的原码为:00000000000000000000000000000001
  2. 因为正数的原码、反码、补码都一样,所以:

    1
    2
    3
    4
    5
    6
    1+1=
    00000000000000000000000000000001
    +
    00000000000000000000000000000001
    =
    00000000000000000000000000000010(二进制逢二进一)
  3. 00000000000000000000000000000010转换为十进制为:1*2^1=2

1-2

  1. 在数学中减法也可以转换为加法,因此1-2=1+(-2)
  2. -2的原码=10000000000000000000000000000010
  3. 通过原码得出反码=11111111111111111111111111111101
  4. 通过反码得出补码=11111111111111111111111111111110
  5. 然后通过补码去计算得出结果的补码:

    1
    2
    3
    4
    5
    6
    1+(-2)=
    00000000000000000000000000000001
    +
    11111111111111111111111111111110
    =
    11111111111111111111111111111111
  6. 通过补码求出反码为:

    1
    2
    3
    4
    5
    11111111111111111111111111111111
    -
    00000000000000000000000000000001
    =
    11111111111111111111111111111110
  7. 通过反码得出原码:10000000000000000000000000000001

  8. 二进制转为十进制:
    1
    2
    3
    4
    10000000000000000000000000000001
    =
    1*2^0
    =-1

JAVA中所有的数字变量都是有符号(正负)的?

这句话,还有点争议。在Java中char类型是:16位Unicode字符,取值范围 0 ~ 65535,不存在负数范围,从这点上说:”char类型就是一个无符号数”;

注意点

  1. 正数的原码、反码、补码都一样
  2. 如果想将二进制转为十进制,必须使用二进制的原码