← 返回文章列表

进制转换其实很直观:二进制、十六进制与颜色代码

进制入门

核心思想:按权展开

任何进制的值,都等于每位数字乘基数的位权之和。二进制 1011 = 1×8 + 0×4 + 1×2 + 1×1 = 11。十六进制用 A–F 表示 10–15,所以 0xFF = 15×16 + 15 = 255。想通这一点,转换就只是机械计算。

为什么程序员爱十六进制

1 位十六进制恰好对应 4 位二进制,一个字节(8 位)正好写成 2 个十六进制字符。内存地址、字节序列、颜色都因此用它:#FF5733 = R:255, G:87, B:51,三组十六进制就是三个颜色通道的强度。

几个容易栽的坑

  1. 前导零会丢:"007" 被解析成数字 7,转回字符串就变了,编号、ID 这类请按字符串处理;
  2. 大数精度丢:超过 JS 安全整数(2^53)后精度不可靠,要按字符串处理或用 BigInt;
  3. 浮点不能精确表示:0.1 在二进制里是无限循环小数,进制转换只对整数部分精确,小数部分注意舍入。

常用数值对照

十进制二进制八进制十六进制
10101012A
2551111 1111377FF
1024100 0000 00002000400
655351111 1111 1111 1111177777FFFF

代码示例

// 解析:第二个参数是进制
parseInt('FF', 16);         // 255
Number.parseInt('1010', 2); // 10

// 输出:toString(进制)
(255).toString(16);         // "ff"
(10).toString(2);           // "1010"

// 颜色通道转十六进制(每通道补足两位)
'#' + [255, 87, 51].map(v => v.toString(16).padStart(2, '0')).join('');
// => "#ff5733"

几个常被问到的问题

为什么颜色用 6 位十六进制?每两位表示一个 0–255 的通道值,R/G/B 各两位正好 6 位,和一个字节无损对应。支持小数吗?整数为主;小数可先按比例放大成整数再换算。最高支持多少进制?36 进制(用满 0-9 与 a-z)。结果会丢精度吗?基于 BigInt 的运算不会。

动手试试:进制转换、颜色转换