Version 10 of Roman numbers

Updated 2004-05-22 06:49:07

RS (Richard Suchenwirth) - Roman numbers 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 numbers - enjoy!


Sorting roman numbers: 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 numbers from integer:

 proc roman:number {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 numbers 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:number [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


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