首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >为什么计算机只能理解 0 和 1

为什么计算机只能理解 0 和 1

作者头像
Lihua奏
发布2026-06-23 20:32:08
发布2026-06-23 20:32:08
2010
举报

为什么计算机只能理解 0 和 1

为什么计算机不用十进制、二十进制,偏偏就要用 0 和 1?

原因其实很简单,不是它“喜欢”二进制,而是它的硬件决定了它更适合二进制。

计算机内部本质上都是集成电路。集成电路的引脚上,电压通常只有两种明显状态:

  • 0V
  • 高电压(比如 +5V)

两种状态,刚好就可以对应成:

  • 0
  • 1

所以计算机用二进制来处理信息,不是人规定出来的,而是硬件天然就长这样。

二进制是怎么表示数字的

平时在计算机里,经常会把数据按 8 位一组来处理。

8 位二进制数,也叫 1 字节(byte)。

1 字节 = 8 比特(bit)

如果一个二进制数本来不到 8 位怎么办?

那就往高位补 0。

代码语言:javascript
复制
100111
相等于
00100111

二进制怎么算

二进制本质上也是“按位展开”。

从右往左看:

  • 第 1 位是2^0
  • 第 2 位是2^1
  • 第 3 位是2^2
  • 以此类推

比如:

代码语言:javascript
复制
39 -> 00100111
   = 1×2^0 + 1×2^1 + 1×2^2 + 1×2^5
   = 1 + 2 + 4 + 32

这里还有两个词:

  • 这些 、 这种位置权重,叫位权2^02^12^2
  • 这里的 ,叫基数2

二进制不只能表示数字

如果只看到这里,很容易以为:

“哦,二进制就是拿来表示数字的。”

其实不是。

二进制本质上表示的是信息

比如字符也能表示:

代码语言:javascript
复制
'A' -> ASCII = 65 -> 二进制 01000001

也就是说:

  • 数字能变成二进制
  • 字符能变成二进制
  • 图片、声音、本质上最后也都能落到二进制

所以计算机处理信息,说到底就是在处理一堆 0 和 1。

移位运算与乘除运算

移位运算,分左移和右移。

在整数的情况下,你可以先这么理解:

  • 左移:值会变大,通常相当于乘 2
  • 右移:值会变小,通常相当于除 2

比如:

代码语言:javascript
复制
00000010 = 2  -> 左移一位 -> 00000100 = 4
00000100 = 4  -> 右移一位 -> 00000010 = 2

在 C 语言里,常见写法就是:

  • <<左移
  • >>右移
代码语言:javascript
复制
a = 39;
b = a << 2; // 左移两位

那 39 左移两位之后是多少?

当然不是 3900。

因为这里不是十进制字符串后面补 0,而是对它的二进制位做移动。

代码语言:javascript
复制
39 = 00100111
左移两位 -> 10011100 = 156

不过这里要注意一点:

移位这种“乘 2 / 除 2”的理解,主要是拿来帮助你理解整数

像 、 这些小数类型,底层虽然也还是二进制,但它们的表示规则和整数不一样,所以不能直接按这个思路去套。floatdouble

补码

前面说的,基本都是正数和 0。

但现实里还有负数,那计算机怎么表示负数?

这里就会用到补码。

先想一个场景

假设现在有个时钟,我让你把 6 点拨到 0 点,怎么做?

你可以:

  1. 往回拨 6 格
  2. 往前拨 6 格

这就是一种“绕圈子”的思路,也就是模运算的感觉。

还要知道一个概念:溢出

比如一个字节全是 1:

代码语言:javascript
复制
11111111

如果再加 1,理论上会变成:

代码语言:javascript
复制
100000000

但问题是,前面那个 已经跑到第 9 位去了,超出了 8 位的范围。1

这时候它就会被丢掉,最后只剩下:

代码语言:javascript
复制
00000000

这就叫溢出。

再来看一个例子

代码语言:javascript
复制
00000010
11111110
--------
100000000

最高位溢出后丢掉,最后就变成了:

代码语言:javascript
复制
00000000

所以在 8 位系统里:

代码语言:javascript
复制
11111110

既可以表示 ,也可以表示 。254-2

关键在于:

你到底是把它当成无符号数,还是有符号数。

这里还有一个很常见的快速规则:

求负数的补码 = 取反 + 1

为什么要发明补码

这里可能还会有一个疑问:

为什么负数非得搞这么麻烦,直接拿一位表示正负不行吗?

当然也不是完全不行,但那样做会带来一个问题:

加减法处理起来很麻烦。

而补码的好处就在于:

CPU 不需要专门搞两套加法规则。

正数、负数,很多时候都可以统一用加法器去算。

所以补码不是“故意搞复杂”,而是为了让硬件更方便处理正负数。

逻辑右移与算术右移

回想前面的右移,对正数来说,前面补 0 就行。

代码语言:javascript
复制
00001000 = 8 -> 右移两位 -> 00000010 = 2

那负数呢?

代码语言:javascript
复制
11111100 = -4

如果你还是机械地往前补 0:

代码语言:javascript
复制
00111111

那这个结果显然就不对劲了。

所以这里就要区分两种右移:

  • 逻辑右移:高位补 0
  • 算术右移:高位补符号位

也就是说:

  • 正数右移时,高位通常补 0
  • 负数做算术右移时,高位通常补 1

所以你不能简单理解成“逻辑右移专门给正数,算术右移专门给负数”,更准确地说:

这是两种不同的补位规则。

符号扩展

符号扩展的逻辑和上面是一样的。

比如:把一个 8 位二进制,在不改变值的情况下,扩展成 16 位

  • 正数:前面补 0 01111111 -> 0000000001111111
  • 负数:前面补 1 11111111 -> 1111111111111111

这样扩展完之后,它表示的值还是原来的值。

逻辑与算术

算术很简单,就是四则运算:

  • +
  • -
  • ×
  • ÷

逻辑运算则是:

  • 逻辑非(NOT)
  • 逻辑与(AND)
  • 逻辑或(OR)
  • 逻辑异或(XOR)

它们的含义分别是:

  • 逻辑非:把 0 变成 1,把 1 变成 0
  • 逻辑与:两边都为 1,结果才为 1
  • 逻辑或:只要有一边为 1,结果就为 1
  • 逻辑异或:两边不一样时结果为 1,一样时结果为 0

这些逻辑运算为什么重要?

因为计算机做判断、做条件控制、做位操作,本质上都离不开这些东西。

最后收一下

这篇讲下来,其实核心就一句话:

计算机之所以能处理信息,是因为它能把各种信息都变成 0 和 1,然后再对这些 0 和 1 做运算。

所以你看到的:

  • 数字
  • 字符
  • 正数
  • 负数
  • 判断
  • 乘除

到了计算机底层,最后都会落到二进制上。

也正因为这样,二进制不是“数学题”,而是计算机处理信息最基础的语言。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 为什么计算机只能理解 0 和 1
    • 二进制是怎么表示数字的
    • 二进制怎么算
    • 二进制不只能表示数字
    • 移位运算与乘除运算
    • 补码
      • 先想一个场景
      • 还要知道一个概念:溢出
      • 再来看一个例子
    • 为什么要发明补码
    • 逻辑右移与算术右移
    • 符号扩展
    • 逻辑与算术
    • 最后收一下
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档