越过浮点数的悬崖依然精确
每一次转换都使用 BigInt 运算。基于普通 JavaScript 数字的转换器在超过 9,007,199,254,740,992 之后就会悄悄出错:问它 9007199254740993,它会返回比它小的那个偶数。而这恰恰是人们从数据库 id 或调试器里粘贴过来的那类数值,所以这个转换器会精确保留它,无论哪种进制,长度最多可达 512 个字符。
用二进制、八进制、十进制、十六进制或 36 以内的任意进制输入一个数,就能同时在其他所有进制中读出它。大整数精确计算,小数真正换算,还能看到它在寄存器中的位模式。
10 进制的 255 等于十进制的 255。
空格、下划线和逗号都会被忽略,所以分组的数值可以直接粘贴。与进制相符的 0b、0o 或 0x 前缀也可以接受。
按无符号它能放进 8 位,但按有符号读则是 -1,因为最高位是 1。
任何进制的数都是一个和:每一位数字乘以进制的位置次幂,位置从右边第 0 位开始数。下面是整数部分在 10 进制下的这个和。
| 数字 | 数值 | 位权 | 贡献 |
|---|---|---|---|
| 2 | 2 | 102 | 200 |
| 5 | 5 | 101 | 50 |
| 5 | 5 | 100 | 5 |
同一个数量的三十五种写法。注意位数如何随着进制增大而减少:这种关系是对数关系,也正是十六进制存在的全部理由。
| 进制 | 值 | 位数 |
|---|---|---|
| 2 | 11111111 | 8 |
| 3 | 100110 | 6 |
| 4 | 3333 | 4 |
| 5 | 2010 | 4 |
| 6 | 1103 | 4 |
| 7 | 513 | 3 |
| 8 | 377 | 3 |
| 9 | 313 | 3 |
| 10你的 | 255 | 3 |
| 11 | 212 | 3 |
| 12 | 193 | 3 |
| 13 | 168 | 3 |
| 14 | 143 | 3 |
| 15 | 120 | 3 |
| 16 | ff | 2 |
| 17 | f0 | 2 |
| 18 | e3 | 2 |
| 19 | d8 | 2 |
| 20 | cf | 2 |
| 21 | c3 | 2 |
| 22 | bd | 2 |
| 23 | b2 | 2 |
| 24 | af | 2 |
| 25 | a5 | 2 |
| 26 | 9l | 2 |
| 27 | 9c | 2 |
| 28 | 93 | 2 |
| 29 | 8n | 2 |
| 30 | 8f | 2 |
| 31 | 87 | 2 |
| 32 | 7v | 2 |
| 33 | 7o | 2 |
| 34 | 7h | 2 |
| 35 | 7a | 2 |
| 36 | 73 | 2 |
进制只是选择用多少个符号计数后再进位。数量 255 写成 11111111、377 还是 FF,本身都不会变,变的只是记法。因此,转换整数部分就是反复除以目标进制,转换小数部分就是反复相乘,而这里两者都在精确整数上完成,而不是用浮点数。这一区别就是这个工具全部的技术含量:正因如此,一个十九位的标识符来回转换后仍然完好无损;也正因如此,无法用二进制写尽的十进制小数会被标为循环小数,而不是被悄悄舍入成一个看起来整齐却是错误的值。
二进制、八进制、十进制和十六进制一键即选,2 到 36 的任意进制也可以直接输入。空格、下划线和逗号都会被忽略,所以从十六进制转储或电子表格中复制的分组数值可以直接粘贴。与进制相符的 0b、0o 或 0x 前缀会被接受并去掉。
四种常用进制加上一个你自选的目标进制会随输入实时更新,每一个都可以单独复制。下方还会把同一个值用 2 到 36 全部三十五种进制写出来,位数如何减少一目了然,而不用靠文字描述。
寄存器面板展示这个整数放进 8、16、32 或 64 位时的样子,有符号和无符号两种读法并排显示。计算过程面板把数字拆成每一位数字乘以进制的位置次幂,这正是位值记数法的定义,也是手工验算转换最快的办法。
每一次转换都使用 BigInt 运算。基于普通 JavaScript 数字的转换器在超过 9,007,199,254,740,992 之后就会悄悄出错:问它 9007199254740993,它会返回比它小的那个偶数。而这恰恰是人们从数据库 id 或调试器里粘贴过来的那类数值,所以这个转换器会精确保留它,无论哪种进制,长度最多可达 512 个字符。
小数部分以精确的分数保存:分子除以进制的位数次幂,再通过反复乘除来转换。因此,十进制的 0.1 转成二进制是 0.0001100110011…,并被标为循环小数而不是被悄悄舍入。这也最清楚地说明了为什么在大多数编程语言中 0.1 加 0.2 不等于 0.3。
选择 8、16、32 或 64 位,即可同时看到存储的位模式、无符号读法和有符号读法。超出位宽的值会按溢出回绕显示而不是被拒绝,因为寄存器本来就是这么做的。看到 300 在一个字节里变成 44,往往正是打开这个转换器的原因。
在八进制数中输入 9,提示会告诉你 9 的值是九,而八进制最大只到 7,并在该字符下方用脱字符 ^ 标出位置。只会清空结果的转换器,只能让你自己去找输错的地方。
二进制和十六进制按 4 位或 8 位分块,十进制使用千位分隔符,不合适的地方两者都不用。分组后的结果按显示的样子原样复制,0b、0o 和 0x 前缀可开可关,取决于要放进正文还是源代码。
从 2 进制到 36 进制,每种进制旁边都标出位数。对数关系因此一目了然:一个字节需要 8 位二进制数字、3 位十进制数字和 2 位十六进制数字,这正是十六进制而不是八进制成为二进制简写的原因。
把每一位数字乘以 2 的位置次幂(从右边第 0 位开始数),再把结果相加。以 1011 为例,就是 1×8 + 0×4 + 1×2 + 1×1,结果为 11。数值较长时,倍增法更快:从最左边的数字开始,每次把当前累计值翻倍,再加上下一位数字。1011 的过程是 1,然后 2+0 = 2,然后 4+1 = 5,然后 10+1 = 11。本页的计算过程面板会逐位列出第一种方法,方便你对照验算。
因为 16 进制需要十六个不同的数字,而十进制只提供了十个。A 到 F 补上了缺口,分别代表十到十五。之所以想要十六这个基数,是因为 16 是 2 的 4 次方,恰好四位二进制数字对应一位十六进制数字,既没有余数,彼此之间也没有进位。因此一个字节总是两个十六进制字符,内存转储、颜色代码和 MAC 地址也都是这样写的。八进制同样有这个性质,每位对应三个比特,它输给十六进制主要是因为一个字节是八位而不是九位。
补码把负数存储为这样一个位模式:它与对应的正数相加后,寄存器会溢出回绕到零。在八位中,负一是 11111111,因为 11111111 加 00000001 溢出后得到 00000000。之所以优先用补码而不是简单的符号位,是因为这样加法和减法都不需要特殊处理:同一个加法电路就能处理正负两种符号,比较运算也照样有效。而原码(符号加数值)表示法还会产生正零和负零两个零,每段代码都得记得去处理。
道理和三分之一在十进制中不精确一样。一个分数在某种进制下能写成有限小数,只有当分母的所有质因数都能整除这个进制时才行。十分解为二和五,所以十分之几、五分之几和二分之几在十进制中都是有限小数。二的质因数只有它自己,所以二进制小数只有在分母是 2 的幂时才能写尽。十分之一的分母不是,于是 0.1 变成无限循环的 0.000110011001100…,任何固定宽度的格式都只能在某处截断。正是这种截断,让 0.1 加 0.2 在大多数编程语言中得到 0.30000000000000004。在这里以十进制为源进制输入 0.1,二进制那一行会直接显示出循环。
它是用数字 0 到 9 加上拉丁字母表的二十六个字母所能容纳的最大进制,因此是在不区分大小写、又便于键入的前提下最紧凑的数字写法。这让它很适合短标识符和 URL 别名(slug):一个需要十位十进制数字的值,用 36 进制只要六个字符。实际中常常更偏好 32 进制,因为它去掉了容易看混的字符,又能整齐地对应五个比特;62 进制则更进一步,让大小写也有区别,代价是这样的标识符没法在电话里念给别人听。
可以。在前面输入负号,所有进制都会显示同样的符号,因为负号是数值本身的属性,而不是记法的属性。寄存器面板才是有意思的地方:固定宽度的寄存器没有符号字符,它存的是补码位模式。所以负 42 在八位中是 11010110,按无符号读就是 214。两种读法会一起显示,并附有说明:你的编程语言会给出哪一种,取决于该类型是有符号还是无符号。
它会溢出回绕,页面也会注明这一点。三百放不进八位,所以寄存器里存的是 44,也就是 300 减 256。这不是转换器出错,而是硬件本来的行为,把它重现出来比拒绝回答更有用。寄存器面板上方的转换不受影响:它们精确且不设上限,唯一的限制是输入最多 512 个字符。
接受,前提是前缀与你选择的进制相符。在设为十六进制的输入框中,0x1F 读作 31;同一个字符串在进制设为二进制时就是真正的不匹配,所以 x 会被报告为无效数字,而不是被悄悄忽略。输出前缀是另一个独立开关:值要放进源代码时打开,要放进正文或电子表格单元格时关闭。
因为位数是一个对数。用 b 进制写一个数 n,大约需要以 b 为底 n 的对数那么多位,所以提高进制会减少位数,但减少得很慢:进制翻倍,按数值每增长一个二进制位来算,你也只省下一位数字。这就是为什么 255 需要八位二进制数字、三位十进制数字和两位十六进制数字,也是为什么本页的全进制表格从 2 进制到 10 进制缩短得很快,而从 20 进制到 36 进制几乎没有变化。
不会。所有运算都在这个标签页中用 JavaScript 内置的 BigInt 完成,转换过程不涉及任何请求。从调试器、内部 id 或私钥指纹中粘贴来的值都只留在你的设备上。
探索不断扩充的工具合集,涵盖计算、文档、写作和日常工作。