Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Java code output "NaN"

So here I have this first time app I'm working on. When I run this code in the emulator for some reason I get a "NaN" output. The program essentially is meant to find the lowest price out of several choices (of quantity and price combined). I can't figure out what I'm doing wrong. Any advice?

(Note: The NaN output occurs only when NOT all of the EditText fields have a number in them)

main class:

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;

public class worthit extends Activity implements OnClickListener{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button b = (Button)this.findViewById(R.id.btn_calculate);
    b.setOnClickListener(this);
}

public void onClick(View v){

    //Declaring all of our variables that we will use in 
    //future calculations
    EditText price1 = (EditText)this.findViewById(R.id.price1);
    EditText price2 = (EditText)this.findViewById(R.id.price2);
    EditText price3 = (EditText)this.findViewById(R.id.price3);
    EditText price4 = (EditText)this.findViewById(R.id.price4);

    EditText quant1 = (EditText)this.findViewById(R.id.quant1);
    EditText quant2 = (EditText)this.findViewById(R.id.quant2);
    EditText quant3 = (EditText)this.findViewById(R.id.quant3);
    EditText quant4 = (EditText)this.findViewById(R.id.quant4);

    //TextView box used to present the results
    TextView tv = (TextView)this.findViewById(R.id.result);

    //Declaring two arrays of the values from
    //all of our EditText fields
    double[] price = new double[4];
    double[] quantity = new double[4];

    try{
        price[0] = Double.parseDouble(price1.getText().toString());
        price[1] = Double.parseDouble(price2.getText().toString());
        price[2] = Double.parseDouble(price3.getText().toString());
        price[3] = Double.parseDouble(price4.getText().toString());

        quantity[0] = Double.parseDouble(quant1.getText().toString());
        quantity[1] = Double.parseDouble(quant2.getText().toString());
        quantity[2] = Double.parseDouble(quant3.getText().toString());
        quantity[3] = Double.parseDouble(quant4.getText().toString());

        if
    } catch(NumberFormatException nfe) {
        tv.setText("Parsing Error");
    }

    //Creating a Optimize class and using our
    //price and quantity arrays as our parameters
    Calculate optimize = new Calculate(price, quantity);

    //Calling the optimize method to compute the cheapest 
    //choice 
    optimize.optimize();

    //Composing a string to display the results
    String result = "The best choice is the $" +
            optimize.getResultInDollars() + " choice.";

    //Setting the TextView to our result string
    tv.setText(result);


   }
 }

And here is my class that does all the crunching:

//Work class used for computing whether
//one choice is cheaper than another given
//a choice of several options af different 
//prices and quantities
//Ex. Coffee- $1-10oz, $1.2-12oz, $1.4-16oz

public class Calculate {
//declaring variables
private double[] dollarValue;
private double[] ounce;
private int indexNumber;        //Index number of the lowest ratio
private double minValue;        //Lowest ratio

private double resultInDollars;
private double resultInOunces;


//class constructor
public Calculate(double[] dol, double[] oun){
    //initializing our variables
    dollarValue=new double[dol.length];
    ounce=new double[oun.length];

    //passing the values from the parameter
    //arrays in our arrays
    for(int i=0;i < dol.length;i++){
        dollarValue[i]=dol[i];
        ounce[i]=oun[i];
    }
}

//Optimize method used to compute the
//cheapest price per quantity
public void optimize(){
    //finding the ratio of the dollar value
    //and the quantity (ounces)
    double[] ratio=new double[dollarValue.length];
    for(int i=0;i<dollarValue.length;i++)
        ratio[i]=dollarValue[i]/ounce[i];

    //finding the smallest value in the ratio
    //array and its location (indexNumber)
    minValue = ratio[0];
    for(int i=1;i < dollarValue.length; i++){
        if(ratio[i] < minValue){
            minValue=ratio[i];
            indexNumber=i;
        }
    }

    //finding the dollar value of the smallest
    //ratio that we found above
    //e.g. most cost effective choice 
    setResultInDollars(minValue*ounce[indexNumber]);
    setResultInOunces(ounce[indexNumber]);
}

public void setResultInDollars(double dollarValueChoiche) {
    this.resultInDollars = dollarValueChoiche;
}

public void setResultInOunces(double resultInOunces) {
    this.resultInOunces = resultInOunces;
}

public double getResultInDollars() {
    return resultInDollars;
}

public double getResultInOunces() {
    return resultInOunces;
}

}

Cheers.

EDIT: Apparently I also seem to be having a logic error somewhere. For example, if I choose the following prices: 1.4, 1.6, and I choose the following quantities (respectively) 18, 20, The output tells me that the $1.6 is the best choice; when you do the calculation by hand (1.4/18, 1/6,20) you get that 1.4 has the lowest ratio, thus it has to be the best choice. If anyone could tell me what I'm doing wrong that would be much appreciated.

Thank you.


1 Answers

NaN stands for Not a Number and is a floating point placeholder value that is used when you try to calculate an invalid computation.

The most common such operation is division by zero. Since I see exactly one division in your code (ratio[i]=dollarValue[i]/ounce[i];), I'd guess that ounce[i] is 0 at that point.

Note that you can't check for NaN using ==, because NaN is not equal to any value (not even itself!).

To check if a float/double is NaN use Float.isNaN() and Double.isNaN() respectively.

like image 65
Joachim Sauer Avatar answered Jul 20 '26 23:07

Joachim Sauer