Click to See Complete Forum and Search --> : explanation of code


graemo
05-06-2003, 04:42 PM
can anyone talk me through step by step the code for this converter

any help greatly appreciated!!
cheers

var lastChanged;
var lastDone;
var lastString;
var canAlert = true;
function setLastChanged(field){
lastChanged = field;
lastDone = null;
canAlert=true;
}
function calcNumerals(){
var last = lastDone;
if (last == null){
last = lastChanged;
}
lastDone = last;
if (last.value == ""){
document.numerals.arabic.value = "";
document.numerals.roman.value = "";
return;
}
if (last == document.numerals.arabic){
var arabicInt = parseInt(last.value);
if ("" + arabicInt == "NaN"){
if (canAlert){
alert("That's not a number!");
}
canAlert = false;
last.focus();
last.select();
return;
}
if (arabicInt <= 0){
if (canAlert){
alert("Roman numerals can't be less than one.");
}
canAlert = false;
last.focus();
last.select();
return;
}
if (arabicInt >= 10000){
if (canAlert){
alert("That number is too big to be converted.");
}
canAlert = false;
last.focus();
last.select();
return;
}
document.numerals.roman.value = AtoR(arabicInt);
} else if (last == document.numerals.roman){
var r = RtoA(last.value);
if (r == -1){
if (canAlert){
alert("That doesn't appear to be a valid roman numeral.");
}
canAlert = false;
last.focus();
last.select();
return;
}
document.numerals.arabic.value = r;
document.numerals.roman.value = AtoR(r);
}
}

function set(field, text){
(eval(field)).value = text;
setLastChanged(eval(field));
calcNumerals();
window.scroll(0,0);
}
function RtoA(s){
var c;
var c1;
var v;
var v1;
var arabic = 0;
for(i=0; i<s.length; i++){
c = s.charAt(i);
v = getValue(c);
if (v == -1){
return -1;
}
if (i+1 < s.length){
c1 = s.charAt(i+1);
} else {
c1 = '!';
}
v1 = getValue(c1);
if (v1>v){
arabic += v1-v;
i++;
} else {
arabic += v;
}
}
if (arabic < 10000){
return (arabic);
} else {
return (-1);
}
}
function getValue(c){
var result = -1;
switch (c){
case 'M':{
result = 1000;
} break;
case 'D':{
result = 500;
} break;
case 'C':{
result = 100;
} break;
case 'L':{
result = 50;
} break;
case 'X':{
result = 10;
} break;
case 'V':{
result = 5;
} break;
case 'I':{
result = 1;
} break;
}
return result;
}
function AtoR(i){
var roman = "";
var arabic = i;
while (arabic - 1000 >= 0){
roman += "M";
arabic -= 1000;
}
while (arabic - 900 >= 0){
roman += "CM";
arabic -= 900;
}
while (arabic - 500 >= 0){
roman += "D";
arabic -= 500;
}
while (arabic - 400 >= 0){
roman += "CD";
arabic -= 400;
}
while (arabic - 100 >= 0){
roman += "C";
arabic -= 100;
}
while (arabic - 90 >= 0){
roman += "XC";
arabic -= 90;
}
while (arabic - 50 >= 0){
roman += "L";
arabic -= 50;
}
while (arabic - 40 >= 0){
roman += "XL";
arabic -= 40;
}
while (arabic - 10 >= 0){
roman += "X";
arabic -= 10;
}
while (arabic - 9 >= 0){
roman += "IX";
arabic -= 9;
}
while (arabic - 5 >= 0){
roman += "V";
arabic -= 5;
}
while (arabic - 4 >= 0){
roman += "IV";
arabic -= 4;
}
while (arabic -1 >= 0){
roman += "I";
arabic -= 1;
}
return (roman);
}

Charles
05-06-2003, 05:25 PM
That converter has way too many steps. Try this one instead:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Content-Script-Type" content="text/javascript">

<script type="text/javascript">
<!--
// Roman class constructor
function Roman(n) {
if (Number (n)) {this.value = Math.floor(n)}
else {
var r = {I:1, V:5, X:10, L:50, C:100, D:500, M:1000}
var 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 () {

var 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';
var a = this.value.toString().split('').reverse();
for (j=0; j<a.length; j++) {a[j] = r[j][a[j]]}
var s = a.reverse().join('');
if (s == 'MCMXCIX') {s = 'MIM'};
if (s == 'CXCIX') {s = 'CIC'};
return s;
}

// -->
</script>

<form action="" name="number">
<div>
<p><label>Arabic<br>
<input type="text" name="arabic" onchange="document.forms.number.roman.value = new Roman(this.value)">
</label></p>
<p><label>Roman<br>
<input type="text" name="roman" onchange="document.forms.number.arabic.value = new Roman(this.value).valueOf()">
</label></p>
<div>
</form>

Charles
05-06-2003, 05:39 PM
You'll note that objects of my Roman class have some interesting properties. In JavaScript whenever you try to use an object as a string the toString() method of the object is called automatically. And Roman.toString() returns the roman number as a string. So Alert (new Roman(25)) gives you 'XXV'. But whenever you try to use an object as a number JavaScript automatically calls the valueOf() method which in this case returns the roman number as a number. So alert (new Roman(25) + new Roman(25)) gives you '50'. However, my constructor can take either a number or a Roman Numeral string so alert (new Roman('XXV') + new Roman('XXV')); also gives you '50'.

graemo
05-07-2003, 04:51 AM
Charles thank you for the code but i'm new to all this and am just trying to understand the code I have but what i'll do if you can help I need comments to tell why variables and functions are used for each piece of coding. I'lll then compare the two - i take it the first one is bad coding!!

cheers
Graemo

Charles
05-07-2003, 05:14 AM
Yes, it's very bad. But you cannot learn JavScript that way. And I have a book here that explains it all and it's 776 pages long. You're going to have to read the whole thing to understand what I did and I suggest that you do. If you pick up pieces of JavaScript then you will end up writing realy long scripts when much shorter ones will do the trick. See http://forums.webdeveloper.com/showthread.php?s=&threadid=9053 and http://forums.webdeveloper.com/showthread.php?s=&threadid=3911. The book you need to read is JavaSript : The Definitive Guide by David Flanagan (http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?userid=2UDA3DN7W4&isbn=0596000480&itm=1).