Ashwin Gupta
Ashwin Gupta

Reputation: 2197

Why does this number parser not correctly parse doubles?

I've written a basic number parser that I believe should work for both doubles and integers. However, when called to parse a number, it only works with int types, when the number is a double (which it knows by reaching a decimal point) it simply stops parsing. Can someone please tell me what is wrong with this code:

(Note: the parser is parsing numbers from a file which is previously read into a char array. I know that the contents of the file are read into the array correctly because I print the array contents and it contains the correct contents)

My Number Parser Function:

NumReturn numberParser(int cIndex) { // current index of array where num is
    // found
    int num = 0;
    double dnum;
    // int[] result = new int[2];
    while (Character.isDigit(Lexer.fileContents[cIndex]) == true) {
        num = num * 10 + Character.getNumericValue(Lexer.fileContents[cIndex]);
        System.out.println(num);
        cIndex++;
        if (cIndex >= Lexer.fileContents.length)
            break;
    }

    try {
        if (Lexer.fileContents[cIndex] == '.') {
            dnum = (double) num;
            int n = 1;
            while (Character.isDigit(Lexer.fileContents[cIndex++]) == true) {
                dnum = dnum + Character.getNumericValue(Lexer.fileContents[cIndex]) / (10 * n);
                n++;
                System.out.println(dnum);
                cIndex++;
                if (cIndex >= Lexer.fileContents.length)
                    break;
            }
            System.out.println("Double Value:" + dnum);
            return new NumReturn(dnum, cIndex);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("Int Value:" + num);
    return new NumReturn(num, cIndex);

}

NumReturn class: //even though you probably dont need to see this

package jsmash;

public class NumReturn {
    int value;
    double dvalue;
    int pointerLocation;
    NumReturn(int value, int pointerLocation) {
        this.value = value;
        this.pointerLocation = pointerLocation;
    }
    NumReturn(double dvalue, int pointerLocation) {
        this.dvalue = value;
        this.pointerLocation = pointerLocation;
    }
}

Test Cases:

323 --> parses correctly and prints 323
323.54 --> stops parsing after the decimal and prints 323.0 

Upvotes: 0

Views: 87

Answers (2)

Klitos Kyriacou
Klitos Kyriacou

Reputation: 11621

The problem is this statement:

dnum = dnum + Character.getNumericValue(Lexer.fileContents[cIndex]) / (10 * n);

The / operator has higher precedence, so it is evaluated as this:

dnum = dnum + (Character.getNumericValue(Lexer.fileContents[cIndex]) / (10 * n));

Both sides of the / operator are of type int, so this is an integer division. You are dividing a number < 10 by a number >= 10, so you are always getting 0 as integer division truncates. You need to make at least one of the operands a double, and then it will do floating-point division. However, that's not the end of your problems. Your code divides by 10, 20, 30, .... You want it to divide by 10, 100, 1000, .... Also, you are advancing cIndex twice: inside the while condition, and again in the loop. You should only do it once.

        ++cIndex; // Advance past the decimal point.
        double n = 10;
        while (Character.isDigit(Lexer.fileContents[cIndex])) {
            dnum += Character.getNumericValue(Lexer.fileContents[cIndex]) / n;
            n *= 10;

Upvotes: 2

ketan vijayvargiya
ketan vijayvargiya

Reputation: 5649

Try changing this line:

dnum = dnum + Character.getNumericValue(Lexer.fileContents[cIndex]) / (10 * n);

to:

dnum = dnum + (Character.getNumericValue(Lexer.fileContents[cIndex]) * 1.0) / (10 * n);

In your current code, you are dividing Character.getNumericValue(Lexer.fileContents[cIndex]), which is an int, by a double- this is always equaling 0.0

Upvotes: 1

Related Questions