0

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);
    }
}
Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80

3 Answers3

4

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.

barak manos
  • 29,648
  • 10
  • 62
  • 114
3

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;
}
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • Thank you for the very good answer there. That makes sense. I have fixed my delta value by recomputing it in my main method, however, do you have any insight as to why both my Right and Left Reimann sum methods are returning zero? – Justin Taylor Jan 26 '14 at 19:25
  • @JustinTaylor, when you recompute it, what is `partitions`? If partitions is small then you might run into boundary problems. `<=` on floating point values is dodgy, so your reimann might be more reliable if you treat partition as an `int` and loop over the number of partitions instead. – Mike Samuel Jan 26 '14 at 19:39
  • @JustinTaylor, please see my ammended comment re int looping. – Mike Samuel Jan 26 '14 at 19:49
  • @JustinTaylor, also `end - start / partitions` is equivalent to `end - (start / partitions)` since division has higher operator precedence than subtraction. It is not the same as `(end - start) / partitions` which is probably what you want. – Mike Samuel Jan 26 '14 at 21:40
0

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.

moveaway00
  • 918
  • 1
  • 5
  • 13