Justin Taylor
Justin Taylor

Reputation: 1

My value keeps showing up as NaN

Essentially my delta value is giving me some trouble, when I print all the variables to the console window everything is right and proper except for delta, whose value keeps showing up as NaN. I can't for the life of me figure out why. I am a beginning CIS student at a University and this is really giving me a headache.

import java.util.Scanner;


public class ReimannSumCalculator {
    static double a,b,c,start,end;
    static double partitions;
    static double delta=end - start / partitions;

    private static double Quadratic(double a,double b,double c,double x) {
        double Quadratic = a*x*x + b*x + c;
        return Quadratic;
    }


    public static void leftReiman(double a,double b,double c,double delta,double start,double end) {
        double leftReiman = 0;

        for(double x = start; x<end; x+=delta) {
            leftReiman = delta * Quadratic(a,b,c,x) + leftReiman;
        }

        System.out.println("Your left Reiman sum is " + leftReiman);
    }

    public static void rightReiman(double a,double b,double c,double delta,double start,double end) {
        double rightReiman = 0;

        for(double x = start+delta; x<=end; x+=delta) {
            rightReiman = delta* Quadratic(a,b,c,x) + rightReiman;
        }

        System.out.println("Your right Reiman sum is " + rightReiman);
    }

    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);

        System.out.println("Please enter some values for a b and c.");

        a = keyboard.nextDouble();
        b = keyboard.nextDouble();
        c = keyboard.nextDouble();

        System.out.println("Please enter a start and end point.");

        start = keyboard.nextDouble();
        end = keyboard.nextDouble();

        System.out.println("Now enter the amount of partitions.");

        partitions = keyboard.nextInt();

        leftReiman(a,b,c,start,end,delta);
        rightReiman(a,b,c,start,end,delta);

        System.out.println("The delta is: " + delta);
        System.out.println("The amount of partitions are: " + partitions);
        System.out.println("a is: "+ a);
        System.out.println("b is: "+ b);
        System.out.println("c is: " + c);
        System.out.println("The start is: " + start);
        System.out.println("The end is: " + end);
    }
}

Upvotes: 0

Views: 292

Answers (3)

Mike Samuel
Mike Samuel

Reputation: 120516

Java is not excel. It does not figure out the order of operations for a symbolic expression automatically, or recompute expressions when inputs change.

The burden of getting the order of operations right, and recomputing values when their inputs become stale is on the programmer.

static double a,b,c,start,end;

static double partitions;

static double delta=end - start / partitions;

is equivalent to

static double a,b,c,start = 0.0d, end = 0.0d;

static double partitions = 0.0d;

static double delta=end - start / partitions;

because all fields take on the zero value for their type, which is equivalent to

static double a,b,c,start = 0.0d, end = 0.0d;

static double partitions = 0.0d;

static double delta=0.0d - 0.0d / 0.0d;   // division by zero -> NaN

because fields are initialized in the order of their declaration.

Then you fail to recompute delta in the body of main, so you end up passing a delta of NaN to leftReimann and rightReimann.


It might make sense to use an integer loop to make sure you deal with the right number of partitions instead of comparing a double x to double boundaries. Floating-point operations are lossy, so you can run into boundary conditions when checking doubles in your loop condition.

public static double leftReimann(double a,double b,double c,int partitions,double start,double end) {
    assert partitions > 0;

    double leftReimann = 0;

    double delta = (end - start) / partitions;

    for(int i = 0; i < partitions; ++i) {
        double x = start + delta * i;
        leftReimann += delta * Quadratic(a,b,c,x);
    }

    System.out.println("Your left Reimann sum is " + leftReimann);
    return leftReimann;
}

public static double rightReimann(double a,double b,double c,int partitions,double start,double end) {
    assert partitions > 0;

    double rightReimann = 0;

    double delta = (start - end) / partitions;  // negative

    for(int i = 0; i < partitions; ++i) {
        double x = end + delta * i;
        rightReimann += delta * Quadratic(a,b,c,x);
    }

    System.out.println("Your right Reimann sum is " + rightReimann);
    return rightReimann;
}

Upvotes: 3

moveaway00
moveaway00

Reputation: 917

There's two options, either make delta a function

private double getDelta() { return (end - start) / partitions;

or, you can recalculate delta after you set end, start, or partitions. (in this case, right before your calls to the Reiman functions, you should say:

delta = (end - start) / partitions;

so it uses the new values of end, start, and partitions.

As others have said, at the time you initialize delta, partitions is zero, so division by zero is NaN.

Upvotes: 0

barak manos
barak manos

Reputation: 30136

You are executing start / partitions before you have initialized either one of these variables.

So you're essentially calculating 0.0/0.0, which equals NaN.

Upvotes: 4

Related Questions