Version 12 of Roman numbers

Updated 2004-05-23 05:23:12

RS (Richard Suchenwirth) - Roman numerals

Larry Smith Sorry to interject a pedantic nit here, but these are properly called roman numerals not roman "numbers". A "number" is a pure mathematical concept representing a unique value and is independent of its representation. A "numeral" is a glyph intended to communicate a number. Hence roman "numerals" are a way of expressing numbers. Other ways are base 8 arabic, ascii, or even cuneiform. I have edited the text below to correct this, but the page name should be corrected as well.

Roman numerals are an additive (and partially subtractive) system with the following letter values:

 I=1 V=5 X=10 L=50 C=100 D=500 M=1000; MCMXCIX = 1999

Here's some Tcl routines for dealing with Roman numerals - enjoy!


Sorting roman numerals: I,V,X already come in the right order; for the others we have to introduce temporary collation transformations, which we'll undo right after sorting:

 proc roman:sort list {
    set map {IX VIIII L Y XC YXXXX C Z D {\^} ZM {\^ZZZZ} M _}
    foreach {from to} $map {
        regsub -all $from $list $to list
    }
    set list [lsort $list]
    foreach {from to} [lrevert $map] {
        regsub -all $from $list $to list
    }
    set list
 }

Roman numerals from integer:

 proc roman:numeral {i} {
        set res ""
        foreach {value roman} {
        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} {
                while {$i>=$value} {
                        append res $roman
                        incr i -$value
                }
        }
        set res
 }

Roman numerals parsed into integer:

 proc roman:get {s} {
        array set r_v {M 1000 D 500 C 100 L 50 X 10 V 5 I 1}
        set last 99999; set res 0
        foreach i [split [string toupper $s] ""] {
                if [catch {set val $r_v($i)}] {error "un-Roman digit $i in $s"}
                incr res $val
                if {$val>$last} {incr res [expr -2*$last]}
                set last $val
        }
        set res
 } ;#RS

Roman expressions: With the two above, it's easy to write

 proc roman:expr args {
        regsub -all {[^IVXLCDM]} $args { & } args
        foreach i $args {
                catch {set i [roman:get $i]}
                lappend res $i
        }
        roman:numeral [expr $res]
 } ;#RS
 % roman:expr XXIII*VI
 CXXXVIII
 % roman:expr XXIII+VI
 XXIX

Note that, as entertaining as this construction is, real Romans would have required an explanation. In fact, even among moderns, our conventional symbols for arithmetic operations were only invented at the end of the fifteenth century [link?]. Johann Widmann published a book on mercantile arithmetic in 1489 which used '+' and '-' to indicate surplus and deficit. By 1514, Vander Hoecke first uses the symbols for operations in algebraic expressions. Some time around 1500, then, the burgeoning European market economy and Renaissance "scientific" culture had yielded general recognition of formulae such as "3 + 6 = 9". Before this time, propositions were expressed in terms of human-language words.


PT 13-May-2003: I just noticed that Roman numerals have a slot in the unicode table - beginning at \u2160 for Roman Numeral One and going up to \u2182 Roman Numeral Ten Thousand. Includes some that I didn't know. :)

  string map {
    M \u216f C \u216d D \u216e L \u216c 
    VIII \u2167 VII \u2166 VI \u2165 IV \u2163 V \u2164
    X11  \u216b XI  \u216a IX \u2168 X  \u2169
    III  \u2162 II  \u2161 I  \u2160
  } "VIVIII MCMXVIII MM XLII"

escargo 21 May 2004 - Anybody know why MIM isn't 1999? RS: The rule appears to be that subtraction only applies inside the same "order of magnitude", so 1999 must be MCM(1900)XC(90)IX = MCMXCIX

KPV According to Conway and Guy's The Book of Numbers, the subtraction rule (IV for 4, etc.) was rarely used until medieval times. If that was true, then there were probably some very long Roman numerals: '''MDCCCCLXXXXVIIII' [L1 ].


Additional math functions - Arts and crafts of Tcl-Tk programming - Category Mathematics