首页 技术原理解析内容详情

进制转换为什么是程序员的入门仪式?二进制思维入门

2026-11-03 7 zhuadmin

凌晨一点半,你盯着屏幕上一行大佬写的 `flags & ~0x2`,看了二十分钟没看懂。群里弱弱问了一句,对面甩回来四个字:回炉学进制。

别不服气。进制这玩意儿,是所有程序员都被坑惨了的第一课,也是唯一一门“学一次用十年”的底层功夫。今天把这层窗户纸捅破。

核心要点

  • 计算机用二进制不是因为数学浪漫,是因为电平只有“高/低”两档最稳,想搞十进制电路就是翻车现场。
  • 十六进制不是新知识,它只是二进制的缩写,4 位一组直接换,背都不用背。
  • 左移一位等于乘 2,右移等于除 2,位运算是代码里的黑魔法。
  • 新人两大硬伤:前导零(644 vs 0644)和负数补码(0xFFFFFFFF 为啥是 -1)。

一、为什么是二进制:不是浪漫,是物理学躺平了

二进制:只用 0 和 1 两个状态表示信息,计算机的全部世界观的起点。

先自问一句:计算机为什么不用十进制?搞十档电压,一位就能顶二进制三位多,多优雅?

答案是:电路不答应。要区分 10 个电压档位,每档之间只差零点几伏,一点电磁干扰进来直接把你的 7 读成 8,纯纯翻车。

而两档电平呢?高电平和低电平之间隔着一大段缓冲区,噪声想搞坏它得费老劲了。说人话:灯只有“开/关”最可靠,你做个十档调光器试试?

所以二进制是被物理规律逼出来的选择,不是谁偏心。 别赌运气去研究什么三进制计算机,苏联人上世纪试过了,历史已经给过答案。

二、十六进制:二进制的压缩包

十六进制:用 0-9 和 A-F 共 16 个符号计数,程序员写二进制的官方速记。

这里先破一个迷思:十六进制是一门要重新学的新数制吗?不是,它就是二进制的缩写。

数学依据就一条:16 = 2⁴,所以每 4 个二进制位,正好对应 1 个十六进制位。一一对应,机械转换。

举个例子你就懂了:

```text

1111 1111 = FF

0110 0100 = 64

```

对照关系就 16 组:0000 到 1111,分别对应 0 到 F。F 是 15,四个 1 挨着,完事。

为什么程序员离不开它?因为没人想读 32 个 0 和 1。

  • 颜色 `#FF8000`——两位一拆就是 RGB 三个通道;
  • 内存地址 `0x7ffee4c0a000`——十二个字符表示 48 个二进制位;
  • MAC 地址、哈希值、报文dump,全是十六进制的地盘。

说人话:十六进制就是给二进制做了个 zip 压缩,内容一点没变,体积缩了 4 倍。 躺赚的速记法,不学白不学。

三、位运算:左移乘 2 的黑魔法

位运算:直接对二进制位进行操作,绕过十进制的加减乘除,速度快到犯规。

最经典的一条:`n << 1` 等于 `n * 2`。左移就是在右边补零,`0001`(1)左移一位变 `0010`(2),再移变 `0100`(4)。

为什么?因为二进制里每高一位,权重就翻一倍,跟十进制左移一位变乘 10 是一个道理。

那现代编译器这么聪明,乘法早优化成位移了,还有必要学吗?有,两个原因:面试官考,以及你接盘的老代码里全是它。

几个高频黑魔法,见过就不慌:

  • `n & 1`:判断奇偶,比取模快,末位是 1 就是奇数。
  • `n & (n-1)`:消掉最低位的那个 1,数 1 的个数、判 2 的幂全靠它。
  • `x ^ x = 0`:异或自己等于零,交换变量、找唯一数字的祖传套路。
  • 权限位:Linux 的 `chmod 755`,rwx 就是 4+2+1,`7 = 111` 表示读写执行全开。

见过有新人把权限系统设计成十几个 bool 字段的,查询写了一百行。用位掩码一个 int 就装下了,加权限就是按位或一下。这差距,就是懂和不懂进制运算的差距。

四、新人必踩的两个坑

坑一:前导零不是摆设

前导零:数字前面的 0,在很多语言里代表“这是八进制”,不是好看用的。

经典翻车现场:`chmod 644` 和 `chmod 0644` 在命令行里等价,但在 C、Python 2 里,`0644` 会被解析成八进制的 420,而 `644` 是十进制的六百四十四。差着十万八千里。

JS 里更刺激,老代码 `010` 会被当八进制解析成 8,ES5 之后严格模式直接报错。接盘遗留代码的时候,看到 0 开头的数字先停下来想想,别直接跑。

坑二:负数用补码存,没有负号这回事

补码:负数在计算机里的表示法,按位取反再加一,好处是减法器可以复用加法器。

为什么你打印 `0xFFFFFFFF` 有时候是 4294967295,有时候是 -1?因为 32 个 1 这个东西,到底是啥取决于你怎么“看”它。

无符号解释就是 2³² - 1;有符号解释,最高位是符号位,剩下按补码还原,就是 -1。同一个 bit 串,两种人生。

这也是为什么 `0.1 + 0.2 !== 0.3` 不是 bug——十进制的 0.1 在二进制里是无限循环小数,存进去就被截断了。这不是 JavaScript 的锅,是所有浮点实现共同的宿命,IEEE 754 说了算。

自验一下手算练没练明白的时候,别硬刚脑内推,拿 二进制转换工具 对照着验算,手算结果和工具对不上,八成是哪一步位分组错了,比自己干瞪眼快十倍。

FAQ / 常见问题

Q1:十六进制是不是要重新背一套换算表?

不用。核心就一条“4 位一组”,二进制每 4 位切成一段逐段换,剩下的交给熟练度。

Q2:位运算是上古技术,现在写业务代码用不上吧?

用得上,只是你没意识到。权限掩码、Redis 的 bitmap、协议解析、哈希混淆、前端的颜色运算,底下全是位操作,面试更是年年考。

Q3:0.1 + 0.2 不等于 0.3,是语言设计失误吗?

不是,任何二进制浮点数都存不下十进制的 0.1,这是无限循环小数的天生硬伤。要精确小数就用定点数或 decimal 类型,别赌浮点的运气。

  • 评论列表 (0条)

 暂无评论,快来抢沙发吧~

发布评论