I have to convert octal basis to Decimal but in String format

Viewed 30

I wrote a program which, at first, was giving correct answers however I later wrote another method which caused my program to start failing. After that I deleted the second method but nothing seems to work to fix it. Can you guys tell me what the problem is?

Note: Method isNumeric just checks if the input String contains a non-numeric character.

For example: a number in octal basis "115" needs to be converted to decimal, meaning

(115)8 -> (?)10

The following formula gives us this:

115 = (1 × 8²) + (1 × 8¹) + (5 × 8⁰) = 77

This is the formula that the code is supposed to follow. Therefore the result of the conversion of 115 in octal basis to decimal is 77.

Another limitation of this is that this must use recursion.

It worked in the sense that it gave the correct result 5 times in a row for different String number inputs but something along the way changed and now gives wrong results.

public static int octalStringToDecimal(String numString) {
    //Base case the numeric value is just 0 or where String is empty
    if ((numString.equals(""))) {
        return -9999;
    }
    //the String does not contain numeric characters
    if((!isNumeric(numString))){
        return -9999;
    }
    int rem, sum = 0, i = 0, basis = 8;
    int number = Integer.parseInt(numString); //this is n
    //while our number is not 0 then we keep on parsing
    while (number != 0) {
        rem  = number % 10;
        number = number / 10;
        sum = rem * ((int) Math.pow(basis, i)) + octalStringToDecimal(String.valueOf(number));
        i++;
    }
    //when out number is equal to 0 then we return the value
    return sum;
}

public static boolean isNumeric(String string) {
    try {
        Integer.parseInt(string);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}
1 Answers

Your "recursive" method contains a while loop. Recursive methods do not usually contain loops. A recursive method must contain a condition that terminates the recursion. If that condition is not true, then the method changes the arguments it was called with and then calls itself.

Since the parameter to your recursive method is a string, it seemed logical to me to extract the digits of the number using method substring(int, int).

Since the input number is supposed to be an octal number, apart from checking whether it contains only digits, you also need to check whether it is a valid octal number. In other words each digit in the number must be between 0 (zero) and 7 (seven).

In the below code, I initially take the rightmost digit of the input number and multiply it by 80. Then, in every recursive call, I take the digit immediately to the left of the last digit I converted and increase the exponent by one. Hence, the first recursive call will take the digit to the left of the rightmost digit and multiply it by 81.

Once I have converted the leftmost digit, the recursion stops.

public class Converter {
    private static final int BASE = 8;

    private static void checkDigit(String digit) {
        int numeral = Integer.parseInt(digit);
        if (numeral > 7) {
            throw new IllegalArgumentException("Not a valid octal digit: " + digit);
        }
    }

    private static int convertDigit(String digit, int exponent) {
        return (int) Math.pow(BASE, exponent) * Integer.parseInt(digit);
    }

    private static int octalStringToDecimal(String numString, int exponent, int start) {
        if (start >= 0) {
            String digit = numString.substring(start, start + 1);
            checkDigit(digit);
            return convertDigit(digit, exponent) + octalStringToDecimal(numString, exponent + 1, start - 1);
        }
        else {
            return 0;
        }
    }

    public static void main(String[] args) {
        String numString = "115";
        System.out.println(octalStringToDecimal(numString, 0, numString.length() - 1));
    }
}
Related