From: cupak@rapnet.sanders.lockheed.com (John J Cupak Jr CCP)
Subject: Convert Integer to Roman
Date: Wed, 10 Mar 93 18:11:22 GMT
Date: 1993-03-10T18:11:22+00:00 [thread overview]
Message-ID: <1993Mar10.181122.8706@Rapnet.Sanders.Lockheed.Com> (raw)
I was interested in the solutions to the Integer-to-Roman conversion programs
posted to comp.lang.pascal, so I went home and wrote the Roman.ada function
from a 1969 (!) flowchart. Pascal folks can convert it ;-)
------------------- CUT HERE -----------------------------------
function Roman(The_Number : in Integer) return String is
-- Since many computer manufactures and software houses are expanding their
-- marketing area to foreign countries, it may become necessary to convert
-- an integer number to a Roman Numeral format. Conversion of numbers to
-- Roman Numerals does not lend itself to a mathematical conversion due to
-- lack of symmetrical relationship between the "digits" of the Roman Numeral
-- system. A reduction conversion method is used instead.
--
-- The Romans had no concept of fractions and so all their numerals were
-- integers. At the time their system was initiated, one thousand was as large
-- as could be conceived and was given the letter M (Magna = large). A later
-- modification to the Roman Numeral system extended the range a thousand fold
-- by defining any "digit" with a Bar over it as being 1000 times the normal
-- value. Since it is not possible to create a character with an over-bar, the
-- underscore ("_") is placed on the right of the character, thus M = 1000,
-- M_ = 1,000,000. In this way, numbers as high as one million can be expressed
-- and by use of multiple M_'s, even larger numbers are converted. If all
-- arithmetic is done in integer format, the conversion is exact.
-- This algorithm was extracted from a March 1969 flowchart provided on the
-- SPIRAS PROGRAMMER'S CALENDAR. Spiras Systems, Inc. was (in 1969) an
-- affiliate of USM Corporation, and was based in Waltham, MA.
-- This Ada function was written by John J. Cupak, Jr., CCP
Maximum_Chars : constant Natural := 4; -- Roman Numeral characters
Maximum_Entries : constant Natural := 25; -- Roman Numeral entries
-- Roman Numerals need 1-4 characters
subtype String_Width is Natural 1..Maximum_Chars;
subtype Roman_String is String(String_Width);
-- Information about a single Roman Numeral "digit"
type Roman_Data_Record is
record
Value : Positive;
Width : String_Width;
Chars : Roman_String;
end record;
-- Roman Numeral entries
subtype Array_Entries is Natural range 1..Maximum_Array_Entries;
-- Array of Roman Numeral Data
type Roman_Data_Array is array(Array_Entries) of Roman_Data_Record;
-- Roman Numeral Data
Roman_Data : Roman_Data_Array := ( 1 => (1_000_000, 2, "M_ "),
2 => ( 900_000, 4, "C_M_"),
3 => ( 500_000, 2, "D_ "),
4 => ( 400_000, 4, "C_D_"),
5 => ( 100_000, 2, "C_ "),
6 => ( 90_000, 4, "X_C_"),
7 => ( 50_000, 2, "L_ "),
8 => ( 40_000, 4, "X_L_"),
9 => ( 10_000, 2, "X_ "),
10 => ( 9_000, 3, "MX_ "),
11 => ( 5_000, 2, "V_ "),
12 => ( 4_000, 3, "MV_ "),
13 => ( 1_000, 1, "M "),
14 => ( 900, 2, "CM "),
15 => ( 500, 1, "D "),
16 => ( 400, 2, "CD "),
17 => ( 100, 1, "C "),
18 => ( 90, 2, "XC "),
19 => ( 50, 1, "L "),
20 => ( 40, 2, "XL "),
21 => ( 10, 1, "X "),
22 => ( 9, 2, "IX "),
23 => ( 5, 1, "V "),
24 => ( 4, 2, "IV "),
25 => ( 1, 1, "I "));
Start : Natural := 0; -- Starting position for Roman Numeral "digit"
Finish: Natural := 0; -- Ending position for Roman Numeral "digit"
Result: String(1..80); -- Output Roman Numeral String
Input_Value : Integer;
Index : Array_Entries; -- Index into Roman Numeral Data array
begin
-- Initialize
Input_Value := The_Number; -- Copy in order to decrement later
Index := Array_Entries'First; -- First Roman Numeral Data entry
Result := (others => ' '); -- Blank output string
-- Convert negative number to positive
if Input_Value < 0 then -- Negative number
Start := Start + 1; -- First character
Result(Start) := '-'; -- Negative sign
Input_Value := -Input_Value; -- Make positive
end if;
-- Repeat while still data to convert
while Input_Value > 0 loop
-- Search for next Roman Numeral(s) to insert
while Input_Value < Roman_Data(Index).Value loop
Index := Index'Succ;
end loop;
-- Decrement Input_Value by Roman Numeral Value
Input_Value := Input_Value - Roman_Data(Index).Value;
-- Compute where to insert Roman Numerals in Result string
Start := Finish + 1;
Finish := Start + Roman_Data(Index).Width - 1;
-- Insert from 1 to 4 Roman Numerals in Result string.
Result(Start..Finish) :=
Roman_Data(Index).Chars(1..Roman_Data(Index).Width);
end loop;
return Result(1..Finish);
end Roman_Number; -- Finis
--
John J. Cupak, Jr., CCP Lockheed DECNet: MERVAX::CUPAK
Lockheed Sanders, Inc. Internet : cupak@rapnet.sanders.LOCKHEED.COM
95 Canal Street / NCA15-221 CompuServe : 72411,3176
Nashua, NH 03061-0868 Telephone : (603) 885-2134 FAX: 885-8033
next reply other threads:[~1993-03-10 18:11 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
1993-03-10 18:11 John J Cupak Jr CCP [this message]
1993-03-11 16:37 ` Convert Integer to Roman Mark A. Breland
1993-03-15 7:26 ` Richard A. O'Keefe
1993-03-18 14:23 ` TSRs Mark
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox