Reputation: 85
I am completely new to MIPS, but I am working on trying to convert my java program that takes input from the user in the form of roman numerals and converts it to integers and then prints it out. Here is my Java program:
private static int decodeSingle(char letter) {
switch(letter) {
case 'M': return 1000;
case 'D': return 500;
case 'C': return 100;
case 'L': return 50;
case 'X': return 10;
case 'V': return 5;
case 'I': return 1;
default: return 0;
}
}
public static int decode(String roman) {
int result = 0;
String uRoman = roman.toUpperCase(); //case-insensitive
for(int i = 0; i < uRoman.length() - 1; i++) {//loop over all but the last character
//if this character has a lower value than the next character
if (decodeSingle(uRoman.charAt(i)) < decodeSingle(uRoman.charAt(i + 1))) {
//subtract it
result -= decodeSingle(uRoman.charAt(i));
} else {
//add it
result += decodeSingle(uRoman.charAt(i));
}
}
//decode the last character, which is always added
result += decodeSingle(uRoman.charAt(uRoman.length() - 1));
return result;
}
public static void main(String[] args) {
System.out.println(decode("MCMXC")); //1990
System.out.println(decode("MMVIII")); //2008
System.out.println(decode("MDCLXVI")); //1666
}
I would like to set up the program with the following two arrays. My thought is I can compare whatever the user input is to all_numerals
(i.e. user input is V
compared to V
, which will then give it its value in the index. Once we have the value of the index we can compare to the value of the index in all_values
. I obviously will need a loop to iterate through the user input as well.
# put this somewhere in the data section
all_numerals: .asciiz "IVXLCDMivxlcdm"
all_values: .byte 1, 5, 10, 50, 100, 500, 1000, 1, 5, 10, 50, 100, 500, 1000
My question is: do you have to insert the values for all_numerals
and all_values
into registers or can you just compare the arrays as they are? Being completely new to MIPS is this the most efficient and logical way?
Upvotes: 1
Views: 314
Reputation: 1649
You can substitute switch by nested if-checks and get rid of sub-function calls. This way you don't need to keep the mapping between roman letters and their counterparts in data blocks. They could be hardcoded as constants. In addition such optimization gives me two times speed-up:
public static int decode(String roman) {
int result = 0;
String uRoman = roman; //case-insensitive
int prevPart = -1;
for(int i = 0; i < uRoman.length(); i++) {//loop over all but the last character
int curPart = 0;
int letter = (int)uRoman.charAt(i);
if (letter >= 'a' && letter <= 'z')
letter -= (int)'a' - (int)'A'; // toUpper emulation
if (letter <= (int)'I') {
if (letter == (int)'C') {
curPart = 100;
} else if (letter == (int)'D') {
curPart = 500;
} else if (letter == (int)'I') {
curPart = 1;
}
} else if (letter <= (int)'M') {
if (letter == (int)'L') {
curPart = 50;
} else if (letter == (int)'M') {
curPart = 1000;
}
} else if (letter == (int)'V') {
curPart = 5;
} else if (letter == (int)'X') {
curPart = 10;
}
if (prevPart > 0) {
//if this character has a lower value than the next character
if (prevPart < curPart) {
//subtract it
result -= prevPart;
} else {
//add it
result += prevPart;
}
}
prevPart = curPart;
}
//decode the last character, which is always added
result += prevPart;
return result;
}
Upvotes: 1