初版 | 1, June, 1999 | |
改訂 | 3, June, 1999 | Java採用 |
改訂 | 4, June, 1999 | jar形式 |
ようこそ、ローマ数字変換へ。
このページでは、あなたはローマ数字変換の方法をこっそり学習します。
このコンテンツは、 Java アプレットを利用していますので、Java を実行できる環境でご覧ください。
ローマ数字とは、ローマの人たちが使っていた(る)からローマ数字と呼ばれます。
みもふたもないのですが。
一般的に使われているアラビア数字とは、様々な違いがありますが、なんといっても最大の違いは、ローマ数字には0(ゼロ)がないと言う事でしょう。
また、何やらカッコイイという感じもしないでもありません。
格式張った感じとでもいいましょうか。
ローマ数字では、すべての数を、アラビア数字の10種類(0,1,2,3,4,5,6,7,8,9)よりも少ない、7種類(M,D,C,L,X,V,I)の文字で表します。
漢数字に対しては、数え切れないほど種類がありますので(一、弐、五、厘、毛、十、千、億、恒河沙(ごうがしゃ)などなど。漢数字では、位にも名前がついていますね)、ローマ数字の、あまりのシンプルさに驚きます。
日頃なじみのあるアラビア数字との対応をみると、次のようになります。
M=1000
D=500
C=100
L=50
X=10
V=5
I=1
これを、ふろく2に対応表としてまとめてあるので、ご覧ください。
このように、1と5が基本になっているのも、ローマ数字の特徴と言えるでしょう。
このコンテンツでは、このローマ数字を、どのように表記するかについて扱います。
- ローマ数字は、7種類の記号で数を表現する。
- ローマ数字には、ゼロを表す記号はない。
<目次へ>
Step. 1 までで、ローマ数字の種類と、アラビア数字との対応について理解できたと思います。
ローマ数字では、これらの7種類の文字を組み合わせて(足しあわせて)数を表現します。
例を挙げると、次のようになります。
- 2は、Iを2つ重ねて、
II
と、表現します。( 1 + 1 = 2 )
- 30は、X ( 10 ) を3つかさねて、
XXX
と、表現します。( 10 + 10 + 10 = 30 )
そして、基本的に大きな数を表す記号は、左側に配置します。
例を挙げると、次のようになります。
- 120は、CをひとつとXをふたつ重ねて、
CXX
と、表現します。( 100 + 10 + 10 = 120 )
- 35は、X を3つとVをひとつかさねて、
XXXV
と、表現します。( 10 + 10 + 10 + 5 = 35 )
- ローマ数字では、記号が表す数を足しあわせて、全体の数を表現する。
- 記号は、大きい数を表す記号から順に、左から右へ配置する。
練習問題1
さて、ここで練習問題です。
次のアラビア数字を、ローマ数字に直しましょう 。
Q1)
53
Q2)
2510
Q3)
812
解答は、それぞれ、ボタンを押すと見る事が出来ます。
<目次へ>
これで、一応は、ローマ数字で、数をあらわせる事になりましたが、実は表記する上で、特別のルールがあります。
たとえば、次の場合を考えてみましょう。
- 例題1
46をローマ数字で表してみようこの場合、答えは
XXXXIIIIII
でもよさそうですね?
確かに、間違いではありません。
しかし、実は、このようには、まず書かれないのです。
4は、ローマ数字では、
5 − 1
と、かんがえるのです。
どういう事かと言うと、4を、5と1を使って表現する、ということなのです。
同様に、40や、400も、
40 = 50−10
400 = 500−100
と言うように、考えます。
しかし、それを、どのように表現すればよいでしょうか。
仮に、46を、
LXIIIIII
と表現してしまっては、66と見分けがつかなくなってしまいますね。
そこで、Step. 2 で学んだ方法に、例外が設けられました。
つまり、記号は、大きい数を表す記号から順に、左から右へ配置する、という原則にさからって、
小さな数を、大きな数の左におく
ということにしたのです。
つまり、40は、50−10と考えるので、大きな数の左側に小さな数を書くと言う例外規則に従うと、
XLIIIIII
ということになり、50 - 10 + 1 + 1 + 1 + 1 + 1 + 1 = 46 となり、66と区別がつくようになります。
めでたしめでたし。
と、いいたいところですが、実は、まだ規則があります。
6,7,8と言う数は、それぞれ、
6=5+1
7=5+2
8=5+3
と、考えるのです。
これも、4のときと同じように、5と1,2,3の組み合わせとして、考えるわけです。
かなり、ややこしいのですが、この原則に従うと、6は、5+1ですから
VI
となります。
同様に、7,8も、それぞれ、VII,VIIIと、なります。
従って、例題1の答えは、
XLVI
が、一般的な正解となります。( 46 = 50 - 10 + 5 + 1 )
- 4は、5−1と考え、記号は、大きい数を表す記号から順に、左から右へ配置する規則とは逆に、引きたい数の左側に引く数を配置する。
- 6,7,8は、5+n と考える。
(1 ≦ n ≦ 3 )- 上記の規則は、10倍、100倍されても、かわらない。
(40や400、60,700など。具体的には、IV = 4 や XC = 90 などというように )
練習問題2
さて、ここでお待ちかねの練習問題です。
次のアラビア数字を、ローマ数字に直しましょう 。
Q1)
421
Q2)
374
Q3)
1068
解答は、それぞれ、ボタンを押すと見る事が出来ます。
<目次へ>
ながくなってしまったので、ちょっと一息いれましょう。
算盤は、古代ローマで生まれたと言われています。
アバカスというもので、溝がほってあります。
現在はどうだか知りませんが、算盤の授業があった時代の、算数の教科書に載っている事もあるかもしれません。筆者は、記憶にありませんが。
見た事がある人も、多いのではないでしょうか。
アバカスの整数部の珠の数は、現在つかわれている算盤と、構造的にはまったくかわりません。
が、その天球(上の列の珠のことです)の操作方法は、現在とは逆で、珠を上にあげたときに、値が入ることになっていました。
現在は、下に降ろしたときに、値が入った事になっていますね。
ところで、5の位に記号が割り当てられているから、そろばんの天球ができたのでしょうか。
それとも、逆なのでしょうか。
おもしろいですね。
<目次へ>
さて、気持ちもすっきりしたところで、今度はローマ数字の9について考えてみましょう。
Step. 3 で見てきたように、4には、数字を表す記号の逆転がありました。
実は、9にもそれがあります。
次の例題を考えてみましょう。
- 例題2
9をローマ数字で表してみようこれに対する答えとして、まず最初に
IIIIIIIII
を考えてみましょう。
これは、 I が9つも並んでいて、よくわかりませんが、これを、
5+1+1+1+1
というように考えて、大きい数をあらわす記号を左に配置すると言う原則にあわせると、
VIIII
というように、多少、すっきりした感じにまとめる事が出来ました。
これでも、間違いではありません。
しかし、よくみてみると、5+4となっています。
4 には、例外規則がありました。
それは
4は 5−1 と考える
というものでした。
そこで、
VIV
と書き換える事が出来ますね。
しかし、これでは、6+5なのか5+4なのか、わかりません。
どちらで解釈するかで、値が変わってきてしまうので、大変困ります。
そこで、別の方法を、考えてみます。
たとえば、
9=10−1
と考えてみるとします。
すると、どうなるでしょうか。
4の場合は、引く数は、引かれる数の左側に配置されていましたね。
この場合も同様です。
つまり、X(10) - I(1)ということは、
IX
と書けばよいわけです。
最初の案の IIIIIIIII からくらべれば、たったの2文字で表記できるので、大変すっきりした感じになりました。
従って、例題2の答えは、
IX
が、一般的な解答です。( 9 = 10 - 1 )
- 9は、10−1と考え、4の場合と同様に、引きたい数の左側に引く数を配置する。
- 上記の規則は、10倍、100倍されても、かわらない。
(900はCM、90はXC、など)
練習問題3
さて、またまたお待ちかねの練習問題です。
次のアラビア数字を、ローマ数字に直しましょう 。
Q1)
1921
Q2)
419
Q3)
494
解答は、それぞれ、ボタンを押すと見る事が出来ます。
<目次へ>
さて、これまでみてきたように、色々な規則がある事が分かりましたね。
ですが、さらに例外があります。
次の例題を考えてみましょう。
- 例題3
999をローマ数字で表してみよう
これに対する答えとして、これまでの知識を総動員するとどうなるでしょうか。
4では、5から1を、そして、9では、10から、1を、引いていましたね。
そこで、こういうのはどうでしょうか。
1000−1=999
として、
IM
というのはどうでしょうか?
実際、悪くないように見えます。
ですが、このような表記は、一般的に使われません。
実は、
数を引けるのは、引く数に比べて、5倍か、または10倍を表す記号からだけ
という、暗黙の規則があります。
つまり、
V (5) とX (10) から引けるのはI (1) だけ
ということになるわけです。
たとえば、5をあらわそうとして、
VX
のようにするとします。
しかし、このような、
10−5=5
という表記は、まずありえません。
同様に、
L (50) とC (100) から引けるのはX (10) だけ
かつ
M (1000) と D (500) から引けるのはC (100) だけ
ということになります。
ですので、1000−1、つまり、
IM
という答えは、ありえない事になります。
では、どうするか、といいますと、
999=1000−100 + 100−10 + 10−1
というように計算します。
これを分解すると、
1000−100は CM
100−10は XC
10−1は IX
となります。
これらを組み合わせると、
CMXCIX
となります。
従って、例題3の答えは、
CMXCIX
が、一般的な解答です。( 999=1000−100+100−10+10−1 )
ちなみに、余談になりますが、このコンテンツが書かれた年(1999年)を、ローマ数字で表すと、MCMXCIXとなります。
- 数を引く事が出来るのは、引く数に比べて、5倍か、または10倍を表す記号からだけである。
練習問題4
さて、そろそろうんざりの練習問題です。
次のアラビア数字を、ローマ数字に直しましょう 。
Q1)
3999
解答は、ボタンを押すと見る事が出来ます。
<目次へ>
さて、このコンテンツももそろそろおわりです。
ところで、7種類の文字で数を表すのが、ローマ数字でしたね。
練習問題4の答えは、出せましたか?
ところで、3999の次の4000という数はどうやってあらわすのでしょうか。
また、5000,6000...と言った数はどのようにあらわすのでしょうか。
もう一度、対応表を見てみると、、、。
そうなのです。
もう、記号がありません。
5000をあらわす記号や、10000を表す記号は、もう、ないのです。
では、どうやればいいのでしょう?
実は、それ以上の数は、M (1000) をならべるだけなのです。
いままで見てきたようなルールを、まるで、あざわらうかのようでもあります。
しかし、潔くもあります。
ローマの人たちは、大きな数を必要とする前に、アラビア数字と、出会ったのでしょうか。
自分達の数字とはいえ、たとえば、1999から2000になるとき、
CMXCIX → M
のように、桁数もガックリとかわってしまうのは、さすがに不便すぎたのでしょうか。
しかも、ローマ数字で表された数を一見しても、
なにがなんだかわからない
のが実状ではないでしょうか。
結局、便利なアラビア数字が、世界を席巻して行く事になります。
さて、実用には程遠いローマ数字でしたが、未だに使われているのは、結局、ローマ数字が持つ
気高さ
といったようなようなものなのでしょうか。
余談になってしまいました。
これで、このコンテンツは、おわりです。
長い間、お読み頂いて、まことにありがとうございました。
- ローマ数字には、1000以上をあらわす記号はつかわれない。
- ローマ数字は、実用的ではない。
- ローマ数字は、独特の風致を持つ。
<目次へ>
このくだらないコンテンツに、長長とお付き合い下さって、ありがとうございました。
いわば独特な雰囲気を醸し出す、このローマ数字について、興味を持って頂ければ、このコンテンツを書いた甲斐があると言うものです。
というのは、半分は嘘です。
実際には、古いソースプログラムが出てきたので、それを Java 化してみよう、というだけでした。
その割には、かなりな長文になってしまい、我ながら驚いています。
筆者は、ローマ数字の、非実用性が、好きなのです。
もし、これを読んで、何か誤りがあったり、訂正すべき所がありましたら、こちらまでご連絡下さい。
また、ご意見や、ご感想なども、ございましたら、お寄せいただけますと、大変嬉しく存じます。
<目次へ>
解答と、付録で使われている Java アプレットは、 JDK 1.1.8 で開発したものです。
従って、 1.0.2 API のみをサポートするブラウザでは、正しく動作しないかもしれません。
最近のブラウザは、大丈夫です。
ただし、 Java を実行しないような設定になっていれば、当然動作しません。
まあ、どうせ、たいしたものではないので、動かなくても、気にしないでください。
<目次へ>
JDK、Java は、米国およびその他の国における米国 Sun Microsystems Inc. の商標または登録商標です。
その他の製品名等は、一般にそれぞれ各社の商標または登録商標です。
本文書の著作権は筆者に帰属します。
本文書のプログラムを含むすべての内容は、著者の許諾を得ず、無断で複写、複製をする事は禁じられています。
<目次へ>
概要
- C言語によるアラビア数字文字列からローマ数字文字列へ変換を行うプログラムソースリストです。
使い方
- 引数に変換もとのアラビア数字をASCIZ (NULL止めされた文字列) へのポインタとして与える。
ただし、引数の範囲は ”1\0”〜”4999\0”の間でなければならない。
- 戻値にローマ数字へ変換された文字列を格納した静的バッファへのポインタが返される。
(異常時はNULL)
ご注意
- このプログラムの無断使用を禁じます。
- このプログラムを使用するなどして受けたいかなる損害等は、一切関知しません。
- このプログラムに関するいかなる保証、補償等は、一切行いません。
−−−−ここから−−−−
#include <stdio.h> #include <string.h> /* (c)1987 A.Matsuda pbuf range "1" .. "4999" */ char* roman( const char* pbuf ) { const char* tbl[ ][ 10 ] = { { "", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", }, { "", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc", }, { "", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm", }, { "", "m", "mm", "mmm", "mmmm", "", "", "", "", "", }, }; int len; static char szRoman[100] = ""; char buf[10]; int i; if( !pbuf ){ return NULL; } i = atoi( pbuf ); if( i >= 5000 || 0 >= i ){ return NULL; } sprintf( buf, "%d", i ); szRoman[ 0 ] = '\0'; len = strlen( buf ); i = 0; switch( len ){ default: return NULL; case 4: // down through strcat( szRoman, tbl[ len - i - 1 ][ (buf[ i ] - '0') ] ); i++; case 3: // down through strcat( szRoman, tbl[ len - i - 1 ][ (buf[ i ] - '0') ] ); i++; case 2: // down through strcat( szRoman, tbl[ len - i - 1 ][ (buf[ i ] - '0') ] ); i++; case 1: strcat( szRoman, tbl[ len - i - 1 ][ (buf[ i ] - '0') ] ); } return szRoman; }
−−−ここまで−−−−
ソースプログラムのダウンロードはこちらをクリックして下さい。
<目次へ>
対応表 | ||
---|---|---|
ローマ数字 | アラビア数字 | 漢数字 |
M | 1000 | 千など |
D | 500 | 伍百など |
C | 100 | 百など |
L | 50 | 五十など |
X | 10 | 拾、十など |
V | 5 | 五.伍など |
I | 1 | 一、壱など |
ありません | 0 | 零など |
<ホームページへ>
<目次へ>
<ローマ数字→アラビア数字自動変換へ>
<アラビア数字→ローマ数字自動変換へ>
<アラビア数字←→ローマ数字相互自動変換へ>