Vediamo qualcosa di "utile": il codice per creare una calcolatrice che lavori con i numeri romani. Rispetto alle quattro operazioni di base, ho voluto aggiungere qualcosa di aggiuntivo, per farla più carina. Gli unici limiti per ora sono:
- rappresentazione dei numeri decimali: viene troncata all'intero, dovrei eventualmente gestirla in altro modo
- lo zero!! Possiamo farci poco. Infatti, <<i numeri romani servivano a contare quello che si aveva; come si fa a contare quello che non si ha?>>
Il sistema di numerazione romano si basa su una sequenza di simboli, facendo uso di questa corrispondenza con il sistema decimale:
- I = 1
- V = 5
- X = 10
- L = 50
- C = 100
- D = 500
- M = 1000
Per i multipli (un milione, un miliardo, ecc) non ho implementato simboli diversi, volendo esiste es. con un trattino sopra la lettera, non l'ho implementato poiché con la nostra tradizionale tastiera avremmo problemi ad inserire tali simboli! 😅
Nel programma, abbiamo:
- operatori binari (numeri in entrambe le caselle): addizione, sottrazione, moltiplicazione, divisione, xy
- operatori unari (numero solo nella prima casella): logaritmo naturale, logaritmo in base 10, esponenziale, fattoriale
Osservazione: riuscendo a gestire in qualche modo i numeri decimali, può avere senso aggiungere anche altre funzioni come 1/x, radice quadrata, ecc.
Ecco il codice completo (pagina HTML con codice CSS e JavaScript in blocco):
<!DOCTYPE html>
<html>
<head>
<style>
select,input,button{font-size:2em;}
</style>
</head>
<body>
<h1>Calcolatrice Numeri Romani</h1>
<input type="text" id="input1" placeholder="Numero romano">
<input type="text" id="input2" placeholder="Numero romano">
<select id="operation">
<option value="add">+</option>
<option value="subtract">-</option>
<option value="multiply">*</option>
<option value="divide">/</option>
<option value="x^y">x^y</option>
<option value="ln">ln</option>
<option value="log10">log10</option>
<option value="exp">exp</option>
<option value="x!">x!</option>
</select>
<button onclick="calculate()">Calcola</button>
<div id="result"></div>
<script>
//calcolo fattoriale
function fact(n){
let ris=1
for(let i=n;i>1;i--){
ris*=i;
}
return ris;
}
// Funzione per convertire numero romano in decimale
function romanToDecimal(roman) {
const romanNumerals = {
'I': 1,
'IV': 4,
'V': 5,
'IX': 9,
'X': 10,
'XL': 40,
'L': 50,
'XC': 90,
'C': 100,
'CD': 400,
'D': 500,
'CM': 900,
'M': 1000
};
let decimal = 0;
for (let i = 0; i < roman.length; i++) {
if (i + 1 < roman.length && romanNumerals[roman[i]] < romanNumerals[roman[i + 1]]) {
decimal -= romanNumerals[roman[i]];
} else {
decimal += romanNumerals[roman[i]];
}
}
return decimal;
}
// Funzione per convertire numero decimale in romano
function decimalToRoman(decimal) {
const romanNumerals = [
{ value: 1000, numeral: 'M' },
{ value: 900, numeral: 'CM' },
{ value: 500, numeral: 'D' },
{ value: 400, numeral: 'CD' },
{ value: 100, numeral: 'C' },
{ value: 90, numeral: 'XC' },
{ value: 50, numeral: 'L' },
{ value: 40, numeral: 'XL' },
{ value: 10, numeral: 'X' },
{ value: 9, numeral: 'IX' },
{ value: 5, numeral: 'V' },
{ value: 4, numeral: 'IV' },
{ value: 1, numeral: 'I' }
];
let result = '';
for (const numeral of romanNumerals) {
while (decimal >= numeral.value) {
result += numeral.numeral;
decimal -= numeral.value;
}
}
return result;
}
// Funzione per calcolare l'operazione selezionata
function calculate() {
const input1 = document.getElementById("input1").value.toUpperCase();
const input2 = document.getElementById("input2").value.toUpperCase();
const operation = document.getElementById("operation").value;
if ((input1 === "" || input2 === "" ) && (operation != "ln" && operation != "exp" && operation !="log10" && operation != "x!")) {
alert("Inserisci entrambi i numeri romani.");
return;
}
const decimal1 = romanToDecimal(input1);
const decimal2 = romanToDecimal(input2);
let result;
switch (operation) {
case "add":
result = decimal1+decimal2; break;
case "subtract":
result = decimal1-decimal2; break;
case "multiply":
result = decimal1*decimal2; break;
case "divide":
result = decimal1/decimal2; break;
case "x^y":
result = decimal1**decimal2; break;
case "ln":
result = Math.log(decimal1); break;
case "log10":
result= Math.log10(decimal1); break;
case "exp":
result = Math.exp(decimal1); break;
case "x!":
result = fact(decimal1); break;
default:
alert("Operazione non valida.");
return;
}
const resultRoman = decimalToRoman(result);
document.getElementById("result").innerHTML = "<h2>Risultato (approssimato all'intero nel caso di numeri decimali):</h2>"+`${input1} (${operation}) ${input2} = ${resultRoman}`;
}
</script>
</body>
</html>
Vediamo infine un'immagine di come appare, esempio di utilizzo:

Nel caso 8! che risulta pari a 40320, il risultato in numeri romani (senza includere altre simbologie per "numeri grandi") è MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCCCXX.
Cosa ne pensate? Utile? Vi piace? 😁 Sarebbe interessante estenderne il funzionamento come detto per i numeri decimali e magari con qualche "stratagemma" anche gestire i numeri complessi. Credo che finora nessuno abbia fatto uso dei numeri complessi con il sistema di numerazione romano! 🙂