Search code examples
javaarraylistdoublejava.lang.class

Java Error based around java.lang.NumberFormatException concerning some sort of "infinite" value


I am working on a program which evaluates a given string as a mathematical function at a given x value. I am currently experiencing an error listed as such:

Exception in thread "main" java.lang.NumberFormatException: For input string: "-Infinity3"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at sun.misc.FloatingDecimal.parseDouble(Unknown Source)
at java.lang.Double.parseDouble(Unknown Source)
at function.operateMD(function.java:212)
at function.evaluate(function.java:39)
at Graph.draw(Graph.java:127)
at Graph.main(Graph.java:22)

I am unsure why I am recieving this error. The string sent to the method is "3x-1"

My code essentially takes the String, breaks it into strings of one index, judges what value each of those would be mathematically (i.e. operator, variable, etc.) and runs a series of methods to simplify the function and then evaluate it at a given x value. The method in at which the error occurs (function.operateMD) is here:

public static void operateMD()
{
    double tempPROD=0;
    double tempP1=0;
    double tempP2=0;

    for(int h=0;h<parts.size();h++)
    {
        if(types.get(h).equals("opr"))
        {
            tempP1=Double.parseDouble(parts.get(h-1));
            tempP2=Double.parseDouble(parts.get(h+1));
            if(parts.get(h).equals("*"))
            {
                tempPROD=tempP1*tempP2;
                parts.remove(h+1);
                parts.set(h-1, String.valueOf(tempPROD));
                parts.remove(h);
                types.remove(h+1);
                types.set(h-1, "num");
                types.remove(h);
            }
            else if(parts.get(h).equals("/"))
            {
                tempPROD=tempP1/tempP2;
                parts.remove(h+1);
                parts.set(h-1, String.valueOf(tempPROD));
                parts.remove(h);
                types.remove(h+1);
                types.set(h-1, "num");
                types.remove(h);
            }
        //end of if operator conditional
        }
        else if((h!=parts.size()-1)&&((types.get(h).equals("num"))&&types.get(h+1).equals("num")))
        {
            tempP1=Double.parseDouble(parts.get(h));
            tempP2=Double.parseDouble(parts.get(h+1));
            tempPROD=tempP1*tempP2;
            parts.remove(h+1);
            parts.set(h, String.valueOf(tempPROD));
            types.remove(h+1);
            types.set(h, "num");
        }
    //end loop to go through each part of arraylist
    }
//end of method
}

Note that "parts" is an Arraylist of single-index String values, and "types" is the Arraylist of each of "parts"'s mathematical value.

This is the first programming question I have posted here, so I hope that I have provided enough information.


Solution

  • I have resolved the problem. Basically, the error was reached when trying to evaluate a value -Infinity3 because the loop continually tried to evaluate the function but the ArrayLists were not changed in two ways:

    Firstly, the values that had been evaluated in the function were not removed properly. Secondly, the ArrayLists themselves did not get cleared in each new instance of the .evaluate() method, in which operateMD was called.

    I solved the problem by restructuring the method operateMD as follows:

    public static void operateMD()
    {
        //setTypes();
        double tempPROD=0;
        double tempP1=0;
        double tempP2=0;
    
        for(int h=0;h<parts.size();h++)
        {
            if(types.get(h).equals("opr")&&((types.get(h-1).equals("num"))&&types.get(h+1).equals("num")))
            {
                if(parts.get(h).equals("*"))
                {
                    tempP1=Double.parseDouble(parts.get(h-1));
                    tempP2=Double.parseDouble(parts.get(h+1));
                    tempPROD=tempP1*tempP2;
                    parts.set(h-1, String.valueOf(tempPROD));
                    types.set(h-1, "num");
                    parts.remove(h);
                    parts.remove(h);
                    types.remove(h);
                    types.remove(h);
                }
                else if(parts.get(h).equals("/"))
                {
                    tempP1=Double.parseDouble(parts.get(h-1));
                    tempP2=Double.parseDouble(parts.get(h+1));
                    tempPROD=tempP1/tempP2;
                    parts.set(h-1, String.valueOf(tempPROD));
                    types.set(h-1, "num");
                    parts.remove(h);
                    parts.remove(h);
                    types.remove(h);
                    types.remove(h);
                }
            //end of if operator conditional
            }
            else if((h!=parts.size()-1)&&((types.get(h).equals("num"))&&types.get(h+1).equals("num")))
            {   
                tempP1=Double.parseDouble(parts.get(h));
                tempP2=Double.parseDouble(parts.get(h+1));
                tempPROD=tempP1*tempP2;
                parts.set(h, String.valueOf(tempPROD));
                parts.remove(h+1);
                types.remove(h+1);
            }
        //end loop to go through each part of arraylist
        }
    //end of method
    }
    

    and I added this method to be run before operateMD() was called by the loop:

    public static void clear()
    {
        for(int z=0;z<parts.size();z++)
        {
            parts.remove(z);
            types.remove(z);
        }
    }