Roman numerals
published: 14 April 2019 / updated 12 September 2019
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:
- I, V, X, L, C, D et M,
called Roman numerals, respectively representing the numbers:
- 1, 5, 10, 50, 100, 500 et 1000
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. pp>
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.
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