|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Rzymski system zapisywania liczb zwany też łacińskim – addytywny system liczbowy, w podstawowej wersji używa 7 znaków.
Spis treści |
System rzymski zapisywania liczb wykorzystuje cyfry pochodzenia etruskiego, które Rzymianie przejęli i zmodyfikowali ok. 500 p.n.e. Nadaje się on, co prawda, do wygodnego zapisywania liczb, jest jednak niewygodny w prowadzeniu nawet prostych działań arytmetycznych, oraz nie pozwala na zapis ułamków. Te niewygody nie występują w systemie pozycyjnym.
Rzymianie do zapisywania liczb poza siedmioma, które przetrwały do dziś, używali dodatkowo ligatur ↁ oznaczający 5000, oraz ↂ oznaczający 10000. Dodatkowo stosowano notację pozwalającą zapisywać większe liczby. Wpisanie liczby pomiędzy dwa znaki | oznaczało liczbę stukrotnie większą, a umieszczenie poziomej kreski nad liczbą oznaczało mnożenie przez 1000.
John Wallis w 1655 roku zaproponował użycie symbolu ↀ, oznaczającego 1000 (zamiennie z M), do oznaczania nieskończoności; później dla wygody ten symbol został zniekształcony do znaku ∞, i od tej pory jest on stosowany w tym właśnie znaczeniu.
Liczba zero nie posiada własnego znaku w systemie rzymskim, gdyż "nic" nie było powszechnie uważane za wartość liczby. Wartość 0,5 jest reprezentowana przez znak S (łac. Semis - pół) oraz ł (skreślone l).
W typografii XVIII-w. na kartach tytułowych książek spotykamy wariant zapisu tych liczb z zastosowaniem odwróconej litery C:
Przyjęte było także (obecnie rzadkość) oddzielanie kropką i spacją części liczby oznaczających tysiące, setki i dziesiątki z jednościami, np. M. DC. LXI = 1661.
System rzymski stosowany był w łacińskiej części Europy do końca średniowiecza. Do zapisu dat (zwłaszcza numeru roku), stosowany nawet w wieku XX (np. rok wydania książki, rok produkcji filmu).
Odejmowanie przy zapisywaniu cyframi rzymskimi jak przy zapisie IV czy IX albo XC nie było popularne w zapisie stosowanym przez Rzymian, a upowszechniło się dopiero w średniowieczu.
Obecnie przyjęte jest użycie odejmowania w zapisie liczb:
IX = 9
XL = 40
XC = 90
CM = 900
Dawniej stosowano bardziej złożone odejmowania, np. w zapisie daty MDCXIC = 1689[1].
Do dziś jest jednak używany zwyczajowo do zapisywania liczb w pewnych szczególnych przypadkach. Na przykład w Polsce zapisuje się cyframi rzymskimi: numery liceów (ale nie szkół podstawowych i gimnazjów), numery klas i lat studiów, wieki, tomy dzieł, numery pięter, wydziałów w instytucjach. Zwyczajowo zapisuje się czasami również: miesiące, rok powstania budowli (na ich frontonach) oraz numeruje rozmaite grupy klasyfikacyjne (szczególnie na ich wyższych poziomach).
Cyfry rzymskie nadal bywają wykorzystywane do oznaczania miesięcy w zapisie daty, mimo upowszechnienia się systemu opartego na cyfrach wyłącznie arabskich. Wykorzystanie zapisu rzymskiego pozwala uniknąć dwuznaczności wywołanych stosowaniem różnych wariantów kolejności poszczególnych członów w zapisie (vide np. popularny w USA sposób podawania najpierw miesięcy a potem dni wobec czego zapis „08 11 2010” może być rozumiany albo jako 8 listopada albo 11 sierpnia, natomiast zapis 8 XI 2010 można rozumieć tylko w jeden sposób; przy zapisie z udziałem cyfr rzymskich najczęściej pomija się początkowe 0 przy dniach miesiąca o wartości jednocyfrowej).
Cyfry rzymskie powszechnie stosuje się również w numeracji stuleci (np. XIX wiek — nie dotyczy to tradycji anglosaskiej, gdzie powszechnie stosuje się cyfry arabskie), w imionach władców i papieży (np. Jan Paweł II), nazwach wydarzeń historycznych (II wojna światowa).
Użycie liczby rzymskiej wskazuje czasami na liczebnik porządkowy.
W systemie rzymskim do zapisu liczb używa się 7 liter, z których każda oznacza liczbę według podanej tabeli:
| Znak | Wartość |
|---|---|
| I | 1 |
| II | 2 |
| III | 3 |
| IV | 4 |
| V | 5 |
| VI | 6 |
| VII | 7 |
| VIII | 8 |
| IX | 9 |
| X | 10 |
| XX | 20 |
| XXX | 30 |
| XL | 40 |
| L | 50 |
| LX | 60 |
| LXX | 70 |
| LXXX | 80 |
| XC | 90 |
| C | 100 |
| CC | 200 |
| CCC | 300 |
| CD | 400 |
| D | 500 |
| DC | 600 |
| DCC | 700 |
| DCCC | 800 |
| CM | 900 |
| M | 1 000 |
| MD | 1 500 |
| MM | 2 000 |
Nie istnieją znaki dla liczb większych od 1000, choć można zapisywać większe liczby poprzez zapisanie liczby mniejszej 100 razy i umieszczenie jej między '|' np.:
Innym znakiem pełniącym podobną funkcję jest nadkreślenie oznaczające pomnożenie przez 1000 np.:
Aby utworzyć liczbę, trzeba zestawić odpowiednie znaki, poczynając od tego oznaczającego liczbę największą do tego oznaczającego liczbę najmniejszą.
Jeżeli składnik liczby, którą piszemy, jest wielokrotnością liczby nominalnej, wtedy zapisywany jest z użyciem kilku następujących po sobie znaków, z zachowaniem zasady, by nie pisać czterech tych samych znaków po sobie (choć dawniej się jej nie stosowało), lecz napisać jeden znak wraz ze znakiem oznaczającym wartość większą o jeden rząd (liczbowy).
Cyfry jednakowe są dodawane, cyfry mniejsze stojące przed większymi są odejmowane od nich, cyfry mniejsze stojące za większymi są do nich dodawane.
Można spotkać zapis, w którym minimalizuje się (ogranicza) liczbę znaków. Np. 1999 to normalnie MCMXCIX, ale można również napisać MIM, choć to drugie jest już jednak modyfikacją.
Poszczególne cyfry pochodzą od:
Być może z czasem M zostało przekształcone (lub na odwrót) w grecki znak Φ, skąd może pochodzić D (500) będące prawą połową tego znaku.
Pochodzenie znaku X (10) jest niepewne. Jedna z teorii mówi, że znak V (5) powstał na kształt otwartej dłoni, gdzie jest 5 palców a każde dwa tworzą literę V, X (10) natomiast jest zestawieniem dwóch znaków V.[potrzebne źródło]
Prosta implementacja konwertora do systemu rzymskiego w Javie (zakres nie jest tu podany, jednakże nie jestem pewien czy można kilka znaków "|" zapętlać w sobie):
public class Rome { static String toRome(int i) { String odp = ""; int tmp = (i - (i % 1000)) / 1000; if (tmp > 0) { if (tmp > 3) { System.out.print(">5k\n"); odp += "|" + Rome.toRome(i / 100) + "|"; i -= (i / 100) * 100; } else { //System.out.print("<5k\n"); for (int a = 0; a < tmp; ++a) { odp += "M"; } i -= tmp * 1000; } } tmp = (i - (i % 100)) / 100; if (tmp > 0) { switch (tmp) { case 0: odp += ""; break; case 1: odp += "C"; break; case 2: odp += "CC"; break; case 3: odp += "CCC"; break; case 4: odp += "CD"; break; case 5: odp += "D"; break; case 6: odp += "DC"; break; case 7: odp += "DCC"; break; case 8: odp += "DCCC"; break; case 9: odp += "CM"; break; } } i -= tmp * 100; tmp = (i - (i % 10)) / 10; if (tmp > 0) { switch (tmp) { case 0: odp += ""; break; case 1: odp += "X"; break; case 2: odp += "XX"; break; case 3: odp += "XXX"; break; case 4: odp += "XL"; break; case 5: odp += "L"; break; case 6: odp += "LX"; break; case 7: odp += "LXX"; break; case 8: odp += "LXXX"; break; case 9: odp += "XC"; break; } } i -= tmp * 10; tmp = (i - (i % 1)) / 1; if (tmp > 0) { switch (tmp) { case 0: odp += ""; break; case 1: odp += "I"; break; case 2: odp += "II"; break; case 3: odp += "III"; break; case 4: odp += "IV"; break; case 5: odp += "V"; break; case 6: odp += "VI"; break; case 7: odp += "VII"; break; case 8: odp += "VIII"; break; case 9: odp += "IX"; break; } } i -= tmp * 1; return odp; } }
Konwersja liczb arabskich na liczby rzymskie w PHP:
function decimal2roman($input) { $roman = Array( "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"); $decimal = Array(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1); $romanvalue = ""; for ($i = 0; $i < 13; $i++) { while ($input >= $decimal[$i]) { $input -= $decimal[$i]; $romanvalue .= $roman[$i]; } } return $romanvalue; }
Istnieje też ciekawy algorytm, napisany w Polsce (tzw. algorytm Vaxa), znacznie krótszy i szybszy. Przykładowa implementacja w Javie:
public static String rome(int liczba) { if(liczba <= 0 || liczba >= 4000) throw new IllegalArgumentException(String.format( "Invalid roman number (%d), accepted range: [0,3999]", liczba)); final String cyfryRzymskie = "IVXLCDM"; StringBuilder rzymskie = new StringBuilder(16); for(int cyfra = 0, dzielnik = 5; liczba > 0; ++cyfra, dzielnik ^= 7) { int ileCyfr = liczba % dzielnik; liczba /= dzielnik; while(ileCyfr-- > 0) { int indeks = cyfra; if(ileCyfr > 2) { int nieparzystość = liczba & 1; liczba -= nieparzystość; indeks += nieparzystość + (ileCyfr = 1); } rzymskie.insert(0, cyfryRzymskie.charAt(indeks)); } } return rzymskie.toString(); }
Przykładowa implementacja w PHP:
function rome($N){ $c='IVXLCDM'; for($a=5,$b=$s='';$N;$b++,$a^=7) for($o=$N%$a,$N=$N/$a^0;$o--;$s=$c[$o>2?$b+$N-($N&=-2)+$o=1:$b].$s); return $s; }
Konwerter ten ma ograniczony zakres od 1 do 3999, choć w prosty sposób (np. w ostatnim algorytmie poprzez dopisanie kolejnych symboli w inicjacji zmiennej $c lub cyfryRzymskie) zakres ów można dowolnie rozszerzać.