3Q工具箱
首页 / 教程中心 / 换算与计算

数字的几种写法:进制转换、人民币大写与罗马数字的规则与坑

换算与计算发布于 2026-09-12更新于 2026-09-21

同一个数量,在不同场合有完全不同的写法:程序里写成 0xFF,票据上写成「贰佰伍拾伍元整」,钟表盘上写成 IV。这些写法各有一套规则,规则记混了不是显示难看,而是直接算错、票据被退回。

一、位权:手算进制转换的唯一原理

任何进制转十进制都是同一个动作——把每一位乘上它的位权再相加。二进制的位权是 1、2、4、8、16……

1011(2) = 1×8 + 0×4 + 1×2 + 1×1 = 11

十六进制的位权是 1、16、256、4096……,字母 AF 代表 1015

2F(16) = 2×16 + 15 = 47

反方向是「除基取余、逆序读」:112 得商 5152 得商 2122 得商 1012 得商 01,余数从后往前读就是 1011

真正省时间的是分组换算。因为 16 = 2 ^ 4,十六进制一位正好对应二进制四位;因为 8 = 2 ^ 3,八进制一位对应二进制三位。所以十六进制与二进制之间根本不用经过十进制:0xC3 拆成 C = 11003 = 0011,直接拼成 11000011。反过来 10110101 从右往左四位一组,1011 = B0101 = 5,就是 0xB5。八进制同理,三位一组。

进制转换器把二进制、八进制、十进制、十六进制以及三十二进制、六十四进制放在同一屏,在任意一个输入框里打字,其他框会自动同步,适合校对手算结果。它还带「生成随机数」按钮,练手算的时候可以拿它出题、用其他框对答案。

二、编程里的前缀与补码:工具能做什么、不能做什么

先说工具的实际边界,这直接决定你该怎么输入:

  • 它只处理非负整数。 内部换算把十进制解析为整数,负数与小数不参与转换,十进制输入框会过滤掉负号和小数点。
  • 它不识别 0x0b0o 前缀。 每个输入框只保留自己进制的合法字符,其他字符被直接丢掉。
  • 它的三十二进制与六十四进制是「数位换算」,不是编码。 工具把 A-Z2-7 当作三十二进制的 32 个数位、把 A-Za-z0-9+/ 当作六十四进制的 64 个数位,按位权算成一个整数。这与传输用的 Base64 编码完全是两件事——后者按每 3 字节切成 4 个字符,还带 = 补位。想做 Base64 编解码请用专门的编码工具,别用这里的数位换算。

前缀被过滤这件事有个隐蔽的坑。把 0xFF 粘进十六进制框,x 被过滤后剩 0FF,结果仍是 255,看起来没问题;但把 0b1010 粘进十六进制框,b 本身就是合法的十六进制数位,过滤后剩下 0b1010,会被当成 0xB1010 = 725008。所以规范做法只有一条:粘贴前自己把前缀删掉,并且确认粘进的是对应进制的框。

负数在计算机里用补码表示,这部分需要手算,工具不代劳。补码的规则是「取反加一」,或者更快的算法是 2 ^ 位宽 - |负数|。以 8 位为例,-5 就是 256 - 5 = 251,二进制 11111011。坑在于同一串二进制的含义取决于位宽与是否有符号0x80 在 8 位无符号里是 128,在 8 位有符号里是 -1280xFFFF 在 16 位无符号里是 65535,有符号则是 -1。进制转换器一律按无符号解释,所以你在里面输入 11111011 得到的是 251 而不是 -5,这不是算错,是口径不同。

另外要注意大数精度:JavaScript 的常规数字类型只能精确表示到 2 ^ 53 - 1,也就是 9007199254740991。超过这个量级的整数在浏览器端换算会丢精度,结果的末几位不可信,需要处理超大整数时应改用支持大整数的环境。

三、人民币大写:零、整、角分的规范写法

中文大写数字是 零壹贰叁肆伍陆柒捌玖,单位是 拾佰仟万亿。它存在的唯一理由是防篡改:小写的 1 加两笔就成 73 描一下能变 8,而 改成 改成 在字形上做不到。所以银行结算凭证、发票、合同的金额栏都要求大写,并且规定大小写金额必须一致,不一致的凭证银行不予受理。

规范写法里最容易错的是零和整这两处:

  • 金额到「分」为止。 人民币最小单位是分,大写金额也只写到分,不写厘。
  • 整数金额后必须写「整」或「正」。 1234 元要写成「壹仟贰佰叁拾肆元整」,只写「壹仟贰佰叁拾肆元」不完整。
  • 有分时不写「整」。 1234.56 是「壹仟贰佰叁拾肆元伍角陆分」,后面不加「整」。
  • 角位为零而分位不为零时,必须补写「零」。 1234.05 的规范写法是「壹仟贰佰叁拾肆元零伍分」,漏掉这个「零」就给了篡改空间。
  • 中间连续的零合并成一个「零」。 100005 写「壹拾万零伍元整」,不写成一串零。
  • 万、亿位要按节写。 10502000 是「壹仟零伍拾万贰仟元整」,节与节之间的零不能省。

数字大小写转换一次给出五种结果:中文小写(一千二百三十四)、中文大写(壹仟贰佰叁拾肆)、金额大写(壹仟贰佰叁拾肆元整),以及逐位小写与逐位大写(一二三四、壹贰叁肆,适合电话号码、编号这类「读数字」而不是算数值的场景)。金额大写这一路完全按上面的规范走:整数金额补「整」,角位为零而分位不为零时自动补「零」,1234.05 输出的是「壹仟贰佰叁拾肆元零伍分」。反向也支持:把「壹仟贰佰叁拾肆」还原成 1234,带「元 / 角 / 分 / 整」或「人民币 / ¥」的写法会自动按金额口径解析,「壹佰元零伍分」得到 100.05。工具页附有完整的格式说明,填单前对一眼更稳。

四、罗马数字:加减法则、以及为什么没有零

罗马数字只有七个符号:I1V5X10L50C100D500M1000。组合规则是加减并用:

  • 大符号在前表示相加。 VI = 5 + 1 = 6LX = 50 + 10 = 60
  • 小符号在前表示相减,且只允许六种组合。 只有 IV(4)、IX(9)、XL(40)、XC(90)、CD(400)、CM(900)。也就是说只有 IXC 可以充当减数,而且只能减紧邻的两个量级,IL 表示 49 是错的,49 要写 XLIX
  • 相同符号最多连写三次。 III34 必须写 IV。钟表盘上常见的 IIII 属于传统写法,不符合规范但含义明确。
  • VLD 不能重复。 10 不写 VV

拆解一个稍复杂的例子:1994 = M + CM + XC + IV = 1000 + 900 + 90 + 4,写作 MCMXCIV2026 则是 MM + XX + VI = MMXXVI

这套体系有两个结构性的空缺:没有零,也没有负数。原因是它是记数符号的累加体系,而不是位值制——每个符号自带固定量值,靠拼接表达总量,既不需要一个「空位」符号,也没有表示「相反方向」的机制。这也是为什么罗马数字做不了竖式运算,历史上算账要靠算板辅助。另一个限制是上限:标准符号最大到 M,能表达的范围是 13999,更大的数要在字母上加横线表示乘一千,而横线在普通文本里没法打出来。

罗马数字转换覆盖的正是 13999。数字转罗马时它按 M、CM、D、CD、C、XC、L、XL、X、IX、V、IV、I 的顺序贪心拆解,并把每一步的构成展示出来,可以直接对照上面的例子核验;罗马转数字支持大小写混输,会逐字符解析、标出减法组合,还会判断输入是否规范——像 IIII 会被正确识别为 4,同时提示它不是规范写法。

五、常见误算原因

  • 粘贴时带着 0x0b 前缀。 前缀字符可能被过滤,也可能刚好是合法数位而改变结果,务必自己删掉。
  • 在二进制与十六进制之间绕道十进制。 四位一组直接拼是更快也更不容易错的做法。
  • 用无符号换算去理解负数。 补码要先定位宽,11111011 在 8 位有符号下才是 -5
  • 把六十四进制数位换算当成 Base64 编码。 两者算法不同,结果自然不一样。
  • 金额大写漏写「整」或漏补「零」。 这两处是票据被退回的高频原因。
  • 罗马数字用了不允许的减法组合。 ILIC 这类写法不合规,49XLIX99XCIX

常见问题

为什么我输入负数,进制转换器没有反应? 工具只处理非负整数,负号会被输入过滤掉。需要看负数的二进制表示,请先确定位宽,用 2 ^ 位宽 - |负数| 手算出补码对应的无符号值,再把这个值填进十进制框换算。

十六进制和二进制怎么快速互转? 按四位一组拆分:十六进制每一位展开成四位二进制,二进制从右往左每四位合成一个十六进制位。0xC3 对应 1100001110110101 对应 0xB5。八进制则是三位一组。

大写金额里「零」到底什么时候要写? 中间有空位时要写,末尾不写。角位为零而分位不为零,必须写成「元零几分」,1234.05 是「壹仟贰佰叁拾肆元零伍分」;金额是整数则写「元整」;写到「角」为止的,「角」后面可以写「整」也可以不写。数字大小写转换的金额大写按这套规则自动处理,补「零」和补「整」都不用自己判断,写到「角」为止时不额外加「整」。

罗马数字能表示零吗?为什么工具只支持到 3999? 不能。罗马数字是符号累加体系而非位值制,没有表示空位的零,也没有负数。上限则是因为标准符号最大是 M(1000),超过 3999 需要在字母上加横线表示乘一千,普通文本无法表达,所以工具把范围限定在 13999

文中用到的工具

同类教程