웹 개발을 하다 보면 십진수(아라비아 숫자)를 로마 숫자로 변환해야 하는 경우가 종종 있습니다. 예를 들어 챕터 번호, 목차, 게임 UI 등에서 로마 숫자가 활용되곤 하는데요. 이번 글에서는 JavaScript를 활용해 십진수를 로마 숫자로 손쉽게 변환하는 방법을 알아보겠습니다.
변환 원리
로마 숫자는 기본적으로 I(1), V(5), X(10), L(50), C(100), D(500), M(1000)의 조합으로 표현됩니다. 여기에 4와 9처럼 작은 수가 큰 수 앞에 오는 감산 표기(CM = 900, XL = 40 등)까지 고려하면, 다음과 같은 값-기호 쌍을 만들 수 있습니다.
- 1000 → M
- 900 → CM
- 500 → D
- 400 → CD
- 100 → C
- 90 → XC
- 50 → L
- 40 → XL
- 10 → X
- 9 → IX
- 5 → V
- 4 → IV
- 1 → I
이 배열을 내림차순으로 정렬해 두고, 입력값에서 차례대로 뺄 수 있을 때마다 해당 기호를 결과 문자열에 붙여주는 방식으로 변환이 이루어집니다.
예제 코드
아래는 십진수를 로마 숫자로 변환하는 전체 JavaScript 예제입니다.
<!DOCTYPE html>
<html>
<body>
<script>
// 로마 숫자 기호 배열
var romanNum = new Array();
romanNum = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"];
// 십진수 값 배열
var dNum = new Array();
dNum = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
function decimalRoman(value) {
if (value <= 0 || value >= 4000)
return value;
var romanNumeral = "";
for (var i = 0; i<romanNum.length; i++) {
while (value >= dNum[i]) {
value -= dNum[i];
romanNumeral += romanNum[i];
}
}
return romanNumeral;
}
document.write(decimalRoman(39));
document.write("<br>"+decimalRoman(145));
document.write("<br>"+decimalRoman(520));
</script>
</body>
</html>실행 결과
XXXIX CXLV DXX
코드 설명
1. 배열 준비: 로마 숫자 기호(romanNum)와 그에 대응하는 십진수 값(dNum)을 같은 순서로 배열에 담습니다. 반드시 값이 큰 순서부터 정렬되어 있어야 올바른 변환이 가능합니다.
2. 유효성 검사: decimalRoman() 함수는 0 이하이거나 4000 이상인 값은 처리하지 않고 그대로 반환합니다. 표준 로마 숫자 표기법은 일반적으로 1~3999 범위의 수만 표현할 수 있기 때문입니다.
3. 반복 변환: for 문으로 배열을 순회하면서, 현재 값이 해당 자릿수 값보다 크거나 같으면 값을 빼고 대응하는 로마 기호를 결과 문자열에 추가합니다. 이 과정을 while 문으로 반복하여 같은 기호가 여러 번 사용될 수 있도록 합니다(예: III = 3).
정리
이 방식은 그리디(greedy) 알고리즘에 기반한 것으로, 가장 큰 값부터 차감해 나가기 때문에 항상 올바른 로마 숫자 표기를 얻을 수 있습니다. 코드 구조가 단순해서 초보자도 이해하기 쉬우며, 필요에 따라 함수를 확장해 유효 범위 검사나 에러 메시지 출력 등을 추가할 수도 있습니다.