计算工具 · 数学计算

罗马数字

罗马↔阿拉伯(含扩展)

本地处理 · 不上传 免费 · 无需登录 无次数限制 累计 53 次使用
任一栏可编辑实时互转 · 支持 1–3,999,999(含上划线扩展)
罗 马 数 字
基 本 符 号Symbols · 点击填入
减 法 规 则Subtractive pairs
常 用 速 查Quick reference · 点击查看
规则:小数在大数左边表「减」(IV=4),右边表「加」(VI=6);同一字母最多连写 3 次(III=3,IIII 不合法,用 IV)。 扩展:超过 3999 时在字母上加横线(vinculum)表示 ×1000,如 V=5000、X=10000,本工具支持到 3,999,999。
就绪 · 输入数字或罗马数字即时互转
第一节

关于本工具

About

翻译《哈利·波特》同人时,罗马数字“MCMXCVIII”卡住了——它代表1998年。这个工具在浏览器里即时互转罗马与阿拉伯数字,支持从“I”到“MMMCMXCIX”(1-3999)的标准范围,也处理带减性记法(如IV、XL)的扩展输入。所有计算在本地完成,字符不离开设备,适合校对历史年份、章节编号或游戏成就代码。

使用场景

古籍校勘页码

整理一部明代刻本影印件,原书用罗马数字标注卷次和页数,但扫描件模糊,卷XXVII和卷XXIV的「V」与「I」粘连难辨。用本工具将模糊字符转成阿拉伯数字后比对原书目录,发现三处页码错位。工具支持扩展写法如「IV」与「IIII」的相互转换,避免因历史版本差异导致校勘错误。

钟表维修铭文

一块18世纪法国座钟,机芯背面刻有「XII·IX·III」等刻度标记,但部分罗马数字被氧化覆盖。用本工具将可辨认的片段输入,反向推导出缺失数字应为「VI」,并验证了指针装配角度。工具支持带分隔符的输入格式,不必手动清理铭文中的标点符号。

电影片头字幕

为一部历史题材短片制作片尾版权声明,需按行业惯例用罗马数字标注制作年份(2024→MMXXIV)。但导演要求年份下方同时显示阿拉伯数字,且「M」与「CM」的写法需符合《芝加哥格式手册》规范。用本工具一次生成两种格式,并检查出「2024」不应写成「MXXIV」(漏了第二个M)。

化学实验编号

实验室新采购一批试剂瓶,原厂标签用罗马数字I至XII标注批次,但管理员发现编号XII的瓶子实际装的是第11批试剂。用本工具将全部12个编号批量转为阿拉伯数字,发现编号XI(11)被误标为XII。工具支持连续范围转换,无需逐条手动输入。

法律条文引用

起草一份涉外合同,需引用《法国民法典》第1382条(Code civil, Article MCCCLXXXII)。但对方提供的英文译本中条款号混用了罗马数字和阿拉伯数字,且第1382条在旧版中写作「MCCCLXXXII」,新版改为「1382」。用本工具将两种编号互转,确认新旧版对应关系无误,避免引用错误。

对比矩阵

维度本工具在线转换站手工/离线方式
转换范围支持标准罗马↔阿拉伯,含扩展符号(如带横线的大数)多数仅支持标准 1-3999,扩展符号需手动处理依赖记忆或查表,易出错
输入方式直接键入阿拉伯数字或罗马字母,实时转换需选择转换方向,部分需点击按钮手动对照规则或查表,耗时
速度即时转换,无等待需加载页面和网络,有延迟数秒到数分钟,取决于数字大小
隐私数据在浏览器本地处理,不上传服务器数据需发送到服务器,有隐私风险完全离线,无数据泄露
离线可用页面加载后完全离线可用需保持网络连接无需网络
准确性算法严格遵循罗马数字规则,无人工误差依赖后端实现,部分站点对扩展符号支持有 bug易因规则混淆(如 4 是 IV 而非 IIII)而出错
第二节

使用指南

Getting Started

使用步骤

  1. 1在「阿拉伯数字」输入框键入整数(如 2024),右侧实时显示罗马数字转换结果(MMXXIV),无需点击按钮
  2. 2在「罗马数字」输入框键入大写字母组合(如 MCMXCVIII),右侧实时显示阿拉伯数字结果(1998),支持 IV、IX 等减法规则
  3. 3点击输入框右侧的「交换」图标,一键互换两组数值,便于反向验证或连续转换
  4. 4展开「扩展模式」开关,输入带横线的罗马数字(如 V̅I̅I̅I̅),工具自动识别并转换为对应阿拉伯数字(8000)

输入输出示例

输入输出说明
2024(阿拉伯 → 罗马)MMXXIV常规:当前年份,验证大数组合规则(M=1000,重复两次;XX=20;IV=4减法)
IV(罗马 → 阿拉伯)4常规:常见减法规则(I在V前表示4),验证基本反向转换
0(阿拉伯 → 罗马)(空字符串或提示“罗马数字无零”)边界:罗马数字系统没有零,工具如何处理零输入——返回空或给出明确提示
3999(阿拉伯 → 罗马)MMMCMXCIX边界:传统罗马数字最大表示(3999),验证大数+多重减法组合(CM=900,XC=90,IX=9)
MMMM(罗马 → 阿拉伯)4000边界:扩展表示(超过3999),验证工具是否支持扩展罗马数字(如用上划线或重复M)
IIII(罗马 → 阿拉伯)4易错:非标准写法(4通常为IV),验证工具是否容错或严格拒绝
XIVI(罗马 → 阿拉伯)15(或提示“无效格式”)易错:非法组合(XIV=14,加I不合规则),验证工具对无效序列的检测能力
3.14(阿拉伯 → 罗马)(提示“仅支持整数”)易错:小数输入,验证工具是否处理非整数并给出明确错误提示

常见错误对照

1.用大写 I 表示 1,但误用了小写 l

✗ 错误输入 lV(小写 L)表示 4
✓ 修复输入 IV(大写 I)表示 4

罗马数字使用大写拉丁字母,小写 l 在视觉上易与数字 1 混淆,工具严格区分大小写,小写 l 会被视为无效字符。

2.连续重复超过三次同一符号

✗ 错误输入 IIII 表示 4
✓ 修复输入 IV 表示 4

标准罗马数字中 I、X、C、M 最多连续重复三次,IIII 不是合法写法,正确表示 4 用减法规则 IV(5-1)。

3.减法规则中减数符号用错

✗ 错误输入 IL 表示 49
✓ 修复输入 XLIX 表示 49

减法规则中 I 只能放在 V 或 X 前(如 IV、IX),不能放在 L 前。49 应分解为 XL(40)+ IX(9)。

4.阿拉伯数字输入含前导零

✗ 错误输入 007 转换为罗马数字
✓ 修复输入 7 转换为罗马数字

罗马数字没有零的概念,前导零(如 007)在工具中可能被解析为 0 或 7,但 0 本身无法转换,应去除所有前导零。

5.扩展规则中误用非标准减法组合

✗ 错误输入 XM 表示 990
✓ 修复输入 CMXC 表示 990

虽然工具支持扩展规则(如 IV 表示 4),但 XM(1000-10=990)不属于标准或常见扩展,正确写法是 CM(900)+ XC(90)。

6.阿拉伯数字超出工具支持范围

✗ 错误输入 5000 转换为罗马数字
✓ 修复输入 3999 或以下数字

标准罗马数字最大表示 3999(MMMCMXCIX),工具若未支持高值符号(如带横线的 V 表示 5000),输入超范围数字会返回错误或无结果。

7.罗马数字中混入空格或连字符

✗ 错误输入 X I V(带空格)表示 14
✓ 修复输入 XIV(无空格)表示 14

罗马数字是连续字符串,空格或连字符会被工具视为分隔符或非法字符,导致解析失败或结果错误。

第三节

工作原理

How It Works

核心公式

阿拉伯数 = Σ (罗马数字符值 × 位置权重),其中位置权重:若当前符值 < 下一符值则取负,否则取正

变量说明

  • 罗马数字符值I=1, V=5, X=10, L=50, C=100, D=500, M=1000
  • 位置权重当前符值与右侧符值比较,小则减,大则加

示例

输入罗马数字 MCMXCIV:M=1000, CM=900 (C=100 < M=1000 → -100+1000), XC=90 (X=10 < C=100 → -10+100), IV=4 (I=1 < V=5 → -1+5)。逐位累加:1000 + (1000-100) + (100-10) + (5-1) = 1000+900+90+4 = 1994。输出阿拉伯数 1994。

输入数字(阿拉伯或罗马)检测方向(含扩展符号)查表转换(逐个符号映射)验证合法性(减法规则 / 重复限制)输出结果(另一进制数字)
输入 / 校验 处理 / 输出 查表转换
第四节

开发者集成

For Developers

6 种主流语言实现,复制即用:

import re # 罗马数字转阿拉伯数字 def roman_to_int(s: str) -> int: roman_map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} total = 0 prev = 0 for ch in reversed(s.upper()): val = roman_map.get(ch, 0) if val < prev: total -= val else: total += val prev = val return total # 阿拉伯数字转罗马数字(支持 1-3999) def int_to_roman(num: int) -> str: if not 1 <= num <= 3999: raise ValueError('数字超出 1-3999 范围') vals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] romans = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'] result = [] for v, r in zip(vals, romans): while num >= v: result.append(r) num -= v return ''.join(result) # 测试 print(roman_to_int('MCMXCIV')) # 1994 print(int_to_roman(2024)) # MMXXIV
// 罗马数字 ↔ 阿拉伯数字(含扩展:支持 1-3999) function romanToInt(s) { const map = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 }; let total = 0, prev = 0; for (let i = s.length - 1; i >= 0; i--) { const val = map[s[i].toUpperCase()] || 0; total += val < prev ? -val : val; prev = val; } return total; } function intToRoman(num) { if (num < 1 || num > 3999) throw new Error('超出范围'); const vals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; const romans = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I']; let result = ''; for (let i = 0; i < vals.length; i++) { while (num >= vals[i]) { result += romans[i]; num -= vals[i]; } } return result; } console.log(romanToInt('MCMXCIV')); // 1994 console.log(intToRoman(2024)); // MMXXIV
package main import ( "fmt" "strings" ) var romanMap = map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} func romanToInt(s string) int { total, prev := 0, 0 for i := len(s) - 1; i >= 0; i-- { val := romanMap[s[i]] if val < prev { total -= val } else { total += val } prev = val } return total } func intToRoman(num int) string { if num < 1 || num > 3999 { panic("超出 1-3999 范围") } vals := []int{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1} romans := []string{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"} var result strings.Builder for i, v := range vals { for num >= v { result.WriteString(romans[i]) num -= v } } return result.String() } func main() { fmt.Println(romanToInt("MCMXCIV")) // 1994 fmt.Println(intToRoman(2024)) // MMXXIV }
// 带类型标注的罗马数字转换 function romanToInt(s: string): number { const map: Record<string, number> = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 }; let total = 0, prev = 0; for (let i = s.length - 1; i >= 0; i--) { const val = map[s[i].toUpperCase()] ?? 0; total += val < prev ? -val : val; prev = val; } return total; } function intToRoman(num: number): string { if (num < 1 || num > 3999) throw new Error('数字超出 1-3999 范围'); const vals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; const romans = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'] as const; let result = ''; for (let i = 0; i < vals.length; i++) { while (num >= vals[i]) { result += romans[i]; num -= vals[i]; } } return result; } console.log(romanToInt('MCMXCIV')); // 1994 console.log(intToRoman(2024)); // MMXXIV
use std::collections::HashMap; fn roman_to_int(s: &str) -> i32 { let map: HashMap<char, i32> = [ ('I', 1), ('V', 5), ('X', 10), ('L', 50), ('C', 100), ('D', 500), ('M', 1000) ].iter().cloned().collect(); let chars: Vec<char> = s.chars().collect(); let mut total = 0; let mut prev = 0; for &ch in chars.iter().rev() { let val = *map.get(&ch).unwrap_or(&0); if val < prev { total -= val; } else { total += val; } prev = val; } total } fn int_to_roman(mut num: i32) -> String { assert!(num >= 1 && num <= 3999, "超出范围"); let vals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; let romans = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]; let mut result = String::new(); for (i, &v) in vals.iter().enumerate() { while num >= v { result.push_str(romans[i]); num -= v; } } result } fn main() { println!("{}", roman_to_int("MCMXCIV")); // 1994 println!("{}", int_to_roman(2024)); // MMXXIV }
<?php function romanToInt($s) { $map = ['I'=>1, 'V'=>5, 'X'=>10, 'L'=>50, 'C'=>100, 'D'=>500, 'M'=>1000]; $total = 0; $prev = 0; for ($i = strlen($s) - 1; $i >= 0; $i--) { $val = $map[strtoupper($s[$i])] ?? 0; $total += $val < $prev ? -$val : $val; $prev = $val; } return $total; } function intToRoman($num) { if ($num < 1 || $num > 3999) throw new Exception('超出范围'); $vals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; $romans = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I']; $result = ''; for ($i = 0; $i < count($vals); $i++) { while ($num >= $vals[$i]) { $result .= $romans[$i]; $num -= $vals[$i]; } } return $result; } echo romanToInt('MCMXCIV') . "\n"; // 1994 echo intToRoman(2024) . "\n"; // MMXXIV ?>
第五节

常见问题

Q & A
罗马数字里 IV 和 IIII 哪个对?为什么有些钟表上用 IIII?

标准罗马数字写法里,4 是 IV(5-1),9 是 IX(10-1),这是现代通用规则。但钟表盘上经常用 IIII 代替 IV,这不是错误,而是历史习惯,大约从 14 世纪开始流行,原因有几种说法:避免 IV 与神话主神朱庇特(IVPITER)的缩写冲突、视觉上平衡盘面、或单纯出于工匠传统。本工具按标准规则转换(4=IV、9=IX),如果遇到钟表上的 IIII,手动改成 IV 即可正常转换。

能不能转很大的数,比如 5000 以上?

标准罗马数字的上限通常是 3999(MMMCMXCIX),因为 4000 需要用 V̅ 上划线表示 5000 减 1000,但上划线在纯文本里无法直接输入。本工具支持扩展写法:大于 3999 的数会用上划线表示千倍,比如 5000 显示为 V̅,10000 显示为 X̅。输入时也支持直接输入带划线的字母(如 V̅),但普通字母 V 只会被当作 5。如果需要转换超大数字,建议用阿拉伯数字输入,工具会自动生成带划线的结果。

我输入了 IIV 它没报错,但结果不对,这算合法吗?

IIV 不是标准罗马数字——减法规则只允许减一位(如 IV、IX、XL),不能连减(如 IIV 表示 5-2=3 是不允许的)。本工具对非标准写法做了宽容处理:它会尝试按字符顺序累加,IIV 会被解析为 1+1+5=7,而不是 3。如果你想要 3,正确写法是 III。建议始终使用标准写法,如果输入后结果看起来不合理,检查是否用了 IIV、IIX 这类非标准组合。

为什么有些罗马数字大写有些小写?转换时大小写有区别吗?

本工具不区分大小写,输入 iv 和 IV 都会识别为 4。大小写的区别主要在于格式习惯:古典文献和正式场合(如书名、电影年份)通常用大写;小写常见于中世纪的文献或装饰性排版。输出时工具默认使用大写,如果需要小写结果,手动将结果字母改为小写即可。注意:带划线的扩展数字(如 V̅)只有大写形式,小写不支持上划线。

这个转换是在我电脑上算的还是上传到服务器?

完全在浏览器本地完成,无需上传任何数据。本工具是纯前端实现(FE),所有转换逻辑由 JavaScript 在浏览器内执行,输入的数字或字母不会离开你的设备。即使断网也能正常使用,刷新页面后历史记录不会保留。如果涉及敏感数据(如编号、密码中的罗马数字),可以放心使用。

为什么有些网站转 1990 是 MCMXC,这里转出来是 MCMXC?

结果应该是一样的,都是 MCMXC(1000 + 900 + 90)。如果看到不同结果,可能原因有:① 对方网站用了非标准写法(如 MCMXXXXC 这种错误格式);② 对方网站对 4 和 9 用了 IIII 和 VIIII 等古老写法;③ 输入时不小心多打了空格或符号。本工具严格遵循现代减法规则(只允许 IV、IX、XL、XC、CD、CM 这六种减法组合),这是最通用、最符合教科书的写法。如果担心结果差异,可以用 4(IV)、9(IX)、40(XL)、90(XC)这几个典型数快速验证。

我想把一段文字里的罗马数字批量转换,能一次贴多个吗?

本工具目前是单次转换模式,一次只能处理一个罗马数字或一个阿拉伯数字。如果需要批量处理,可以分多次操作,或者把需要转换的罗马数字逐个复制粘贴进来。如果文本中罗马数字夹杂在普通单词里(比如 'Chapter IV'),工具会把 IV 识别为 4,但 'Chapter' 会报错——建议先手动提取出罗马数字部分再转换。未来版本可能会加入批量识别功能,但目前需要逐个操作。

隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

选择 打开 +新窗口 esc关闭