Cfs0004
Cfs0004

Reputation: 85

Java to Mips with two arrays

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

Answers (1)

rsutormin
rsutormin

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

Related Questions