Search code examples
javabigintegerbigdecimal

Exception in thread "main" java.lang.NumberFormatException: Radix out of range


I am trying to take a text file with fractions on it. Convert the fractions from strings to bigdecimal. Then divide and store the results on a stack.

Each line in the txt file is one fraction which was randomly generated with the char '/' separating the numerator and denominator. The numerator and denominator can be of length 1-50 and must be greater than 0. The numbers are generated randomly resulting in the need of storing decimal places. In my code I convert the string to BigInteger first and then to BigDecimal. This works for the first string but breaks on the numerator of the second string.

public static void main(String[] args) throws FileNotFoundException {
    File file = new File("C:/Users/eric/workspace/sortProj/src/data.txt");

    FileReader fr = new FileReader(file);
    Scanner scanner = new Scanner(fr);
    Stack<BigDecimal> pile = new Stack<BigDecimal>();
    String numerator = "";
    String denominator = "";

    while (scanner.hasNextLine()) {
        String str = scanner.nextLine();
        numerator = "";
        denominator = "";

        separateStrings(pile, numerator, denominator, str);
    }
}


// appends chars to numerator string until it hits '/' then appends chars to
// denominator string
public static void separateStrings(Stack<BigDecimal> stack,
        String numerator, String denominator, String source) {
    boolean isNumerator = true;
    for (int i = 0; i < source.length(); i++) {
        if (source.charAt(i) == '/') {
            isNumerator = false;

        }
        else if (isNumerator == true) {
            numerator += source.charAt(i);          
        }else{
            denominator += source.charAt(i);
        }
    }
             //converts and stores fractions.

    BigDecimal BD2 = new BigDecimal(new BigInteger(denominator, denominator.length()));
    BigDecimal BD1 = new BigDecimal(new BigInteger(numerator, numerator.length()));
    stack.push(BD1.divide(BD2, 20, BigDecimal.ROUND_FLOOR));
}

I got this error.

Exception in thread "main" java.lang.NumberFormatException: Radix out of range at java.math.BigInteger.(Unknown Source) at sorting.separateStrings(sorting.java:60)<---Being where I try to convert the numerator to BigInteger.

at sorting.main(sorting.java:26)<--- where I call separateStrings.

The string that it broke on was numerator = "9821020392310432153773517114542035029"

I'm not sure why I'm getting this error. I was under the impression that BigInteger can be up to length 50. Plus, it worked on the first line of txt which was "8731472450870/1572580584296783758".


Solution

  • The error is caused by the object:

    new BigInteger(denominator, denominator.length())
    

    which is attempting to create a BigInteger with radix of 37, exactly 1 more than the allowed maximum of 36.

    In this example you probably didn't need to set the radix or even use BigInteger, so you could simply use:

    BigDecimal bigDecimal = new BigDecimal(denominator);