Binary

记录二进制及其应用

1. 二进制简介

2为基数的计数系统,通常用两个不同的数字01来表示;每个数字称为1个二进制位或者比特(Bit,Binary digit的缩写)。

1. 二进制发展历史

  • 现代的二进制计数系统由Gottfried Wilhelm(von)Leibniz1679年设计,在他1703年发表的文章《论只使用付好0和1的二进制算术,兼论其用途及它赋予伏羲所使用的古老图形的意义》
  • 1854年,英国数学家George Bloole发表了一篇里程碑式的论文《The Laws of Thought》,其中详细介绍了一种代数化的逻辑系统,后人称之布尔代数。它提出的逻辑演算在后来的电子电路设计中起基础性作用。
  • 1937年,Claude Elwood Shannon在麻省理工大学发表其硕士学位论文《继电器与开关电路的符号分析》,其理论奠定了数字电路的理论基础。
  • 1937年11月,任职于贝尔实验室的乔治·斯蒂比兹发明了用继电器表示二进制的装置。它是第一台二进制电子计算机。

2. 算术运算

1. 加法(逢二进一)

0 + 0 = 0
0 + 1 = 1 + 0 = 1
1 + 1 = 0 (进位为1)
1 + 1 + 1 = 1(进位为1)
  • 例如:11101011相加过程如下:

2. 减法(借一有二)

0 - 0 = 0 
1 - 1 = 0
1 - 0 = 1
0 - 1 = 1(借位为1)
  • 例如:1101减去1011的过程如下:

3. 乘法(参照十进制)

 1 * 1 = 1
 0 * 1  = 1 * 0 = 0 
 1 * 1 = 1 
  • 例如:10011010相乘的过程如下:

4. 除法 (参照十进制)

 0 ÷ 0 = 0 
 1 ÷ 0 = 0 (0 ÷ 1 无意义)
 1 ÷ 1 = 1
  • 例如:100110除以110的过程如下:

5. 进制转换

小数示例:

\[(111.01)_2~ = (1\times2^2) + (1\times2^1) + (1\times2^0) + (0\times2^{-1}) + (1\times2^{-2}) = 7.25 \]

3. 位运算

  • 分析:位运算与算术运算的差异
    • 位运算符只对整数起作用,如果一个运算子不是整数,会自动转为整数后再执行
    • 位运算中,位于位之间不像加减运算那样有进位或错位的联系

1. (or)运算符

符号为|,如果两位之一为 1 则设置每位为 1,否则为0

2. (and)运算符

符号为 &,如果两位都是 1 则设置每位为 1,否则为0

3. (not)运算符

符号为 ~,表示对一个二进制位取反,1取反为0,反之

4. 异或(xor)运算符

符号为 ^,如果两位只有一位为 1 则设置每位为 1,否则为0

5. 左移(left shift)运算符

符号为 <<,表示将一个数的二进制值向移动指定的位数,尾部补0,即乘以2的指定次方

6. 右移(right shift)运算符

符号为 >>,表示将一个数的二进制值向移动指定的位数,尾部补0,即除以2的指定次方(最高位即符号位参与移动);如果是正数,头部全部补0;如果是负数,头部全部补1

7. 头部补零的右移(zero filled right shift)运算符

符号为>>>,表示一个数的二进制形式向移动时,头部一律补零,而不考虑符号位。该运算总是得到正值。与>>区别主要在于负数

4. 机器数中的原码、反码、补码(以8bit为例)

1. 机器数

一个数在计算机中的二进制表示形式,叫做这个数的机器数,机器数是带符号的

2. 真值

带符号位的机器数对应的真正数值

3. 原码

原码就是符号位加上真值的绝对值,即第一位表示符号位,其余位表示数值

[+1] = 0000 0001

[-1] = 1000 0001

8bit的二进制数原码取值范围 [ -127 , 127 ]

4. 反码

正数的反码就是其本身

负数的反码是在原码的基础上,符号位不变,其余各个位取反

[+1] = [0000 0001] = [0000 0001]

[-1] = [1000 0001] = [1111 1110]

5. 补码

正数的补码就是其本身

负数的补码是在原码的基础上,符号位不变,其余各位取反,最后+1(即在反码的基础上+1

[+1] = [0000 0001] = [0000 0001] = [1000 0000]

[-1] = [1000 0001] = [1111 1110] = [1111 1111]

  • 思考:为何要使用原码、反码、补码🤔

    人脑可以记住第一位为符号位,但是计算机无法辨别符号位;为了让符号位也参与计算,原码的正数部分带符号位运算是没有毛病的,但是负数呢 ?

    • 1-1 = 1 + (-1) = [0000 0001] + [1000 0001] = [1000 0010] = -2 ?? 显然是不对的!

    于是就诞生了反码

    • 1-1 = 1 + (-1) = [0000 0001] + [1000 0001] = [0000 00001] + [1111 1110] = [1111 1111] = [1000 0000] = -0 🤔

    发现用反码计算减法,结果的真值部分是正确的,而唯一的问题其实就出现在0这个特殊的数值上,虽然人们理解上+0-0是一样的,但是0带符号是没有任何意义的,而且会有[0000 0000]和[1000 0000]两个编码表示0

    于是又诞生了补码

    • 1-1 = 1 + (-1) = [0000 0001] + [1000 0001] = [0000 00001] + [1111 1111] = [0000 0000] = [0000 0000] = 0 OK 没毛病了!
  • 思考:关于补码的取值范围🤔

    • ( -1 ) + ( -127 ) = [1000 0001] + [1111 1111] = [1111 1111] + [1000 0001] = [1000 0000]

      发现可以用[1000 0000]表示-128

      即补码的取值范围为[-128 , 127]

关于补码的取值范围,我总感觉这种解释逻辑还是有些牵强,网上查了很多资料,众说纷纭,但是总感觉有点怪怪的~若有错误请大佬指正,非常感谢!

此次笔记引用了以下网站:

https://zh.m.wikipedia.org/zh-hans/二进制
https://blog.csdn.net/qi_ming88/article/details/77677305
https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/computercode.html
https://www.zhihu.com/question/20458542 注:补码取值范围问题

posted @ 2020-12-30 21:29  Kuiperbelt  阅读(275)  评论(0)    收藏  举报