JS数字转二进制或十六进制字符串怎么写?

作者:工具松鼠

时间:2026-11-02

浏览:665

详细解析在JavaScript中如何将数字转换为二进制或十六进制字符串。涵盖Number.prototype.toString基础语法、字面量直接调用的语法陷阱、固定位宽补零格式化、负数32位无符号补码处理以及超大整数BigInt的转换方案。

文章目录
在 JavaScript 中,将数字转换为二进制或十六进制字符串的标准做法是调用数字的 toString(radix) 方法,并将目标进制(基数)作为参数传入:转二进制传入 2(即 num.toString(2)),转十六进制传入 16(即 num.toString(16))。在实际工程中,结合 padStart 实现固定位宽对齐补零、利用无符号右移运算符 >>> 0 解析负数补码,以及使用 BigInt 突破安全整数边界,便能完整覆盖全部应用场景。
JS数字转二进制或十六进制字符串怎么写?
JavaScript 数字进制转换核心流水线架构图

一、基础写法:Number.prototype.toString(radix)

JavaScript 的 Number 原型对象提供了内置方法 toString([radix])。该方法接收一个介于 2 到 36 之间的整数参数 radix,表示基数(进制数)。如果省略参数,默认按照十进制输出。

1. 转为二进制字符串

将 radix 设置为 2,返回由 '0' 和 '1' 组成的字符串:

const decimalNum = 42;
const binaryStr = decimalNum.toString(2);

console.log(binaryStr); 
// 示例输出: "101010"

2. 转为十六进制字符串

将 radix 设置为 16,返回由数字 0-9 与小写字母 a-f 组成的十六进制字符串。如果业务需要大写字母表示(例如某些硬件协议或色彩代码),可直接链式调用 toUpperCase():

const decimalNum = 255;
const hexLower = decimalNum.toString(16);
const hexUpper = decimalNum.toString(16).toUpperCase();

console.log(hexLower); // 示例输出: "ff"
console.log(hexUpper); // 示例输出: "FF"

二、语法陷阱:为什么字面量直接调用会报错?

许多初学者直接在数字字面量后写点调用方法时,会遭遇语法解析错误:

// 错误示例:会直接抛出 SyntaxError
255.toString(16); // SyntaxError: Invalid or unexpected token

原因解释:JavaScript 词法分析器在扫描到数字后的第一个点号 . 时,会优先将其解析为浮点数的小数点(例如 255.0)。紧随其后的字母 t 无法组成合法的浮点数字符序列,词法分析便在此时崩溃并抛出异常。

规避该词法冲突有以下四种合规写法:

  1. 使用分组括号包裹数值(最推荐):(255).toString(16)。括号强制将 255 作为一个完整表达式求值,括号外的点号被正确识别为属性访问器。
  2. 双点语法:255..toString(16)。第一个点号被词法分析器判定为浮点数的小数点,第二个点号则顺理成章地被识别为调用属性/方法。
  3. 添加空格隔离:255 .toString(16)。数字与点号之间的空格强制截断了数字 Token 的扫描。
  4. 将数值赋给变量后调用:const n = 255; n.toString(16);。变量名标识符绝不会被误认为数字,这是业务代码中最自然的形式。
JS数字转二进制或十六进制字符串怎么写?
图 1:字面量直接调用 toString 的词法冲突与四种合规写法

三、工程格式化:固定位宽对齐与前缀修饰

在处理网络协议、加密哈希、二进制掩码或十六进制颜色代码时,系统往往要求固定位宽(例如单字节必须是 8 位二进制、2 位十六进制,缺失的高位需要补 0)。

原生 toString() 返回的是紧凑字符串(不会自动补充前导零)。例如 (5).toString(2) 只返回 "101"。为了将其格式化为标准的单字节 8 位表示,可结合 ES2017 引入的 String.prototype.padStart():

// 1. 二进制单字节对齐(固定 8 位宽,不足前置补 0)
const byteVal = 5;
const binFormatted = byteVal.toString(2).padStart(8, '0');
console.log(binFormatted); // 示例输出: "00000101"

// 2. 十六进制单字节对齐(固定 2 位宽)
const hexByte = byteVal.toString(16).padStart(2, '0');
console.log(hexByte); // 示例输出: "05"

// 3. 组装标准十六进制颜色代码 (#RRGGBB)
const r = 255, g = 10, b = 128;
const colorHex = '#' + [r, g, b]
  .map(c => c.toString(16).padStart(2, '0'))
  .join('');
console.log(colorHex); // 示例输出: "#ff0a80"

// 4. 添加规范前缀(0b 或 0x)
const withPrefixBin = '0b' + byteVal.toString(2).padStart(8, '0');
const withPrefixHex = '0x' + byteVal.toString(16).padStart(2, '0');
console.log(withPrefixBin); // 示例输出: "0b00000101"
console.log(withPrefixHex); // 示例输出: "0x05"
注意事项:padStart(targetLength, padString) 当源字符串自身长度已经大于或等于 targetLength 时,会完整保留原始字符串,绝不会发生截断现有数值位的情况。
JS数字转二进制或十六进制字符串怎么写?
图 2:进制转换与固定位宽对齐格式化处理管道

四、进阶处理:负数转换与 32 位无符号补码

当对负数直接调用 toString(2) 或 toString(16) 时,JavaScript 的默认行为是在绝对值的转换结果前简单拼接负号 "-":

const neg = -10;
console.log(neg.toString(2));  // 示例输出: "-1010"
console.log(neg.toString(16)); // 示例输出: "-a"

这种表现形式属于人类视角的代数符号表示。但在计算机硬件底层、数据报文解析或位掩码运算中,负数是以补码(Two's Complement)形式存储的。如果要获取其在内存中真实的 32 位补码二进制或十六进制字符串,需要配合 JavaScript 的无符号右移运算符 >>> 0。

运作原理:位运算符 >>> 会强制将操作数转换为 32 位无符号整数(Uint32)。移动 0 位不会改变位数据,但会使得底层负数补码位模式被直接解释为一个正的无符号整数,从而能够生成完整的补码字符串:

const neg = -10;

// 获取 -10 的 32 位二进制补码字符串
const binTwosComp = (neg >>> 0).toString(2);
console.log(binTwosComp); 
// 示例输出: "11111111111111111111111111110110"

// 获取 -10 的 32 位十六进制补码字符串
const hexTwosComp = (neg >>> 0).toString(16);
console.log(hexTwosComp); 
// 示例输出: "fffffff6"
JS数字转二进制或十六进制字符串怎么写?
图 3:负数原生带符号输出与 32 位无符号补码运算机制对比

五、大数场景:突破 2^53 - 1 边界的 BigInt 转换

JavaScript 中普通的 Number 类型遵循 IEEE 754 双精度浮点标准,能够精确表示的安全整数上限为 Number.MAX_SAFE_INTEGER(即 2^53 - 1 = 9007199254740991)。一旦数值超过此范围,普通的 Number 运算与转换会丢失最低有效位精度。

对于高精度时间戳、雪花 ID(Snowflake ID)、密码学散列或大整数计算,必须使用 BigInt 类型。BigInt.prototype.toString(radix) 同样完整支持 radix = 2 与 radix = 16:

// 超过安全整数范围的大数值
const hugeNum = 9007199254740995n; // 字面量加 n 或 BigInt("9007199254740995")

// 大整数转二进制
const hugeBin = hugeNum.toString(2);
console.log(hugeBin);
// 示例输出: "10000000000000000000000000000000000000000000000000011"

// 大整数转十六进制
const hugeHex = hugeNum.toString(16);
console.log(hugeHex);
// 示例输出: "20000000000003"
特别注意:BigInt 不支持无符号右移运算符 >>>。如果需要对超大负数进行补码计算,必须根据业务预定的字节宽度(如 64 位或 128 位),使用掩码运算手动计算补码(例如 (BigInt.asUintN(64, -10n)).toString(16))。

六、工程速查与技术决策拓扑

为了在实际开发中快速选用恰当的转换语法,下表总结了各种常见业务场景的推荐实现范式:

业务场景 典型目标格式 标准推荐代码 示例结果
常规正整数转二进制 紧凑二进制字符串 (num).toString(2) (10) => "1010"
网络协议/字节流查看 8位对齐二进制 (1 Byte) (num).toString(2).padStart(8, '0') (10) => "00001010"
CSS/十六进制色彩拼接 2位对齐十六进制 (num).toString(16).padStart(2, '0') (10) => "0a"
协议大写十六进制 大写十六进制字符串 (num).toString(16).toUpperCase() (255) => "FF"
负数机器补码转换 32位无符号补码 (num >>> 0).toString(2) / (16) (-1) => "ffffffff"
超长数值/ID转换 高精度进制字符串 BigInt(val).toString(2) / (16) 精确转换无精度损失
JS数字转二进制或十六进制字符串怎么写?
图 4:JS 数字进制转换全场景技术决策拓扑与选型路径

综上所述,JavaScript 数字转二进制或十六进制字符串的核心方法是 num.toString(radix)。在实际业务中,记住字面量需要加括号 (val).toString(...) 以避免词法错误;需要格式化显示时使用 padStart;需要计算机底层位视角时借助 >>> 0 计算补码;而面对超安全整数的大数时使用 BigInt,即可稳健应对所有进制转换需求。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章