Roman numerals

published: 14 April 2019 / updated 12 September 2019

Lire cette page en français

 

Roman Numeration is an additive numbering system used by the ancient Romans. The numbers are represented using symbols combined with each other, in particular by the signs:

called Roman numerals, respectively representing the numbers:

contemporary watches with roman numerals

These abbreviations for notifying and holding numbers do not allow calculations to be made. The Romans used charts to do arithmetic operations.

A number written in Roman numerals reads from left to right. As a first approximation, its value determines by summing the individual values of each symbol, except when one of the symbols precedes a higher value symbol. In this case, subtract the value from the first symbol to the second.

Example: 4 is written in Roman numerals IV (I of V).

In certain places of the Germanic Roman Empire, the quadruple form was used. IV was written IIII. This local notation is still found on old clocks.

astronomical clock with Germanic Roman numerals

Decimal encoding to Roman numerals

The following definitions make it possible to transform a decimal number into Roman numerals.

: vector 
    create ( n -- ) 0 
    do ,  loop  
    does>  ( n -- ) swap cells + @ execute ; 
 
: ,I  
    dup c@ C, ;  : ,V  dup 1 + c@ C, ;  : ,X  dup 2 + c@ C, ; 
 
:noname  ,I ,X          drop ;   
:noname  ,V ,I ,I ,I    drop ;   
:noname  ,V ,I ,I       drop ;  
:noname  ,V ,I          drop ;   
:noname  ,V             drop ;   
:noname  ,I ,V          drop ;
:noname  ,I ,I ,I       drop ;   
:noname  ,I ,I          drop ;   
:noname  ,I             drop ;  
 
' drop ( 0 : no output )  10 vector ,digit 
 
: roman-rec ( numerals n -- )
    10 /mod dup 
    if 
        >r over 2 + r> recurse 
    else 
        drop 
    then 
    ,digit ; 
: roman ( n -- c-addr u )  
    dup 0 4000 within 0= abort" EX LIMITO!" 
    HERE SWAP  s" IVXLCDM" drop swap roman-rec  HERE OVER - ;

You can only convert numbers between 1 and 3999 to Roman numerals.

2019 roman type     \ affiche MMXIX 
  25 roman type     \ affiche XXV
 944 roman type     \ affiche CMXLIV

Other version

create romans 0 , 1 , 5 , 21 , 9 , 2 , 6 , 22 , 86 , 13 ,
    does> swap cells + @ ;
 
: roman-digit  ( a1 n1 a2 n2 -- a3)
    drop >r romans
    begin 
        dup 
    while
        tuck 4 mod 1- chars r@ + c@ over c! char+ swap 4 / 
    repeat
    r> drop drop
;
 
: (split) 
    swap >r /mod r> swap ;
 
: >roman ( n1 a -- a n2)
  tuck 1000 (split) s" M  " roman-digit 100 (split) s" CDM" roman-digit
  10 (split) s" XLC" roman-digit 1 (split) s" IVX" roman-digit nip over -
;
 
create (roman) 16 chars allot

Example:

1999 (roman) >roman type cr 

décodage

create (arabic)
  1000 128 * char M + ,
   500 128 * char D + ,
   100 128 * char C + ,
    50 128 * char L + ,
    10 128 * char X + ,
     5 128 * char V + ,
     1 128 * char I + ,
does>
  7 cells bounds do
    i @ over over 127 and = if nip 7 rshift leave else drop then
  1 cells +loop dup
;
 
: >arabic
  0 dup >r >r
  begin
    over over
  while
    c@ dup (arabic) rot <>
  while
    r> over r> over over > if 2* negate + else drop then + swap >r >r 1 /string
  repeat then drop 2drop r> r> drop
;

Conversion test Roman numerals into Arabic numerals:

s" MMXIX" >arabic .

display 2019