Click to See Complete Forum and Search --> : numeral convertor


graemo
12-09-2002, 11:56 AM
can some one tell me how to reverse the function of this convertor so that when you enter roman numerals the equivalent arabic will be produced.

heres the code

I would really appreciate any help


<HTML>
<HEAD>
<TITLE>Roman Numeral Convertor</TITLE>
<SCRIPT LANGUAGE="JavaScript">

var ones_numerals = new Array();
ones_numerals[0] = "";
ones_numerals[1] = "I";
ones_numerals[2] = "II";
ones_numerals[3] = "III";
ones_numerals[4] = "IV";
ones_numerals[5] = "V";
ones_numerals[6] = "VI";
ones_numerals[7] = "VII";
ones_numerals[8] = "VIII";
ones_numerals[9] = "IX";
var tens_numerals = new Array();
tens_numerals[0] = "";
tens_numerals[1] = "X";
tens_numerals[2] = "XX";
tens_numerals[3] = "XXX";
tens_numerals[4] = "XL";
tens_numerals[5] = "L";
tens_numerals[6] = "LX";
tens_numerals[7] = "LXX";
tens_numerals[8] = "LXXX";
tens_numerals[9] = "XC";
var hundreds_numerals = new Array();
hundreds_numerals[0] = "";
hundreds_numerals[1] = "C";
hundreds_numerals[2] = "CC";
hundreds_numerals[3] = "CCC";
hundreds_numerals[4] = "CD";
hundreds_numerals[5] = "D";
hundreds_numerals[6] = "DC";
hundreds_numerals[7] = "DCC";
hundreds_numerals[8] = "DCCC";
hundreds_numerals[9] = "CM";
var thousands_numerals = new Array();
thousands_numerals[0] = "";
thousands_numerals[1] = "M";
thousands_numerals[2] = "MM";
thousands_numerals[3] = "MMM";
function checkNumber(number)
{
if((parseInt(number) < 4000) && (parseInt(number) > 0))
{
var numeral = createNumeral(number);
if(numeral.indexOf('undefined') == -1)
{
window.document.form.numeral.value = numeral;
}
}else{
alert('Please enter a valid number!!');
}
}
function createNumeral(num)
{
var new_num = num
var thousands = Math.floor(new_num / 1000);
new_num -= thousands * 1000;
var hundreds = Math.floor(new_num / 100);
new_num -= hundreds * 100;
var tens = Math.floor(new_num / 10);
new_num -= tens * 10;
var ones = Math.floor(new_num / 1);
if((thousands == NaN)||(hundreds == NaN)||(tens == NaN)||(ones == NaN))
{
alert('Please enter a valid number!!');
}else{
var array = new Array(thousands,hundreds,tens,ones);
return makeNumeral(array);
}
}
function makeNumeral(place_values)
{
var numeral = "";
numeral += thousands_numerals[place_values[0]];
numeral += hundreds_numerals[place_values[1]];
numeral += tens_numerals[place_values[2]];
numeral += ones_numerals[place_values[3]];
return numeral;
}

</script>


</HEAD>
<BODY>
<div align="center">
<form name="form">
<b>Enter a number between (1-3999) :</b> <input size="5" name="number" ><p>
<input type="button" value="Convert" onclick ="checkNumber(window.document.form.number.value)">
<P><STRONG>Answer : </STRONG> <input name="numeral" ></P>
<P><br>

<table width="20%" align="center" border="1" cellspacing="1" cellpadding="2" >
<tr>
<td>M = 1000</td>
<td>D = 500</td>
<td>C = 100</td>
<td>L = 50</td>
</tr>
<tr>
<td>X = 10</td>
<td>V = 5</td>
<td>I = 1</td>
<td>&nbsp;</td>
</tr>
</table></P>
</form>
</div>


<p>
<P>&nbsp;</P>

</BODY>
</HTML>

Charles
12-10-2002, 07:09 AM
This is a good place for a Class. Put the following someplace separate and apart, at the top of the page or in its own file:

// Roman class constructor
function Roman(n) {
if (typeof n == 'number') {this.value = Math.floor(n)}
else {
r = {I:1, V:5, X:10, L:50, C:100, D:500, M:1000}
a = n.toUpperCase().split('');
this.value = 0;
for (j=0; j<a.length; j++) {
if (r[a[j]] < r[a[j+1]]) {this.value -= r[a[j]]}
else {this.value += r[a[j]]};
};
};
};

// class methods
Roman.prototype.valueOf = function () {return this.value}
Roman.prototype.toString = function () {

r = new Array ();
r[0] = ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'];
r[1] = ['', 'X', 'XX', 'XXX', 'IL', 'L', 'LX', 'LXX', 'LXXX', 'XC'];
r[2] = ['', 'C', 'CC', 'CCC', 'ID', 'D', 'DC', 'DCC', 'DCCC', 'CM'];
r[3] = ['', 'M', 'MM', 'MMM'];

if (this.value == NaN) return NaN;
if (this.value == 0) return '';
if (this.value >= 4000) return 'out of range';
a = this.value.toString().split('').reverse();
for (j=0; j<a.length; j++) {a[j] = r[j][a[j]]}
s = a.reverse().join('');
if (s == 'MCMXCIX') {s = 'MIM'};
if (s == 'CXCIX') {s = 'CIC'};
return s;
}

To us this class, fist declare an object:

numeral = new Roman(1999);
or
numeral = new Roman('MIM');

Then whenever you use the object as a string it will return the value in roman numerals, but when you use it as a number it will return the numeric value of the number. The numeral will write the way you want but you can do arithmetic with it.

Charles
12-10-2002, 06:06 PM
graemo asked for clarification in a private message and it seems there is a character limit on private messages. So...

graemo,

From your post it's not clear what it is that you are trying to accomplish, but you can use that class to convert Roman numerals in either direction. If you want to convert Roman to Arabic then:

<script type="text/javascript" src="roman.js"></script>

<script type="text/javascript">
<!--
numeral = new Roman ('MIM');
alert (numeral.valueOf());
// -->
</script>

Or to convert from Arabic to Roman then:

<script type="text/javascript">
<!--
numeral = new Roman (1999);
alert (numeral.toString());
// -->
</script>

What you are doing is creating an object, 'numeral' of the class 'Roman'. In JavaScript when you treat an object as a string the toString() method is automatically called. Most of the time you do not need to explicitly call it, hence alert(numeral) or document.write('numeral') will both output the Roman version of the object. Likewise, in JavaScript if you treat an object like a number then the valueOf() method is automatically called. Unless you are using the object in some arithmetic, you will find that you do need to use the valueOf method explicitly. And when you oputput a number in JavaScript, Arabic numerals are automatically used. So given numeral = new Roman ('MIM') then alert(numeral + 1) outputs "2000".