Java 我的价值观一直显示为NaN
本质上,我的delta值给了我一些麻烦,当我将所有变量打印到控制台窗口时,除了delta(其值始终显示为NaN)之外,一切都是正确的。我一辈子都不知道为什么。我是一所大学的新生,这真让我头疼Java 我的价值观一直显示为NaN,java,variables,nan,Java,Variables,Nan,本质上,我的delta值给了我一些麻烦,当我将所有变量打印到控制台窗口时,除了delta(其值始终显示为NaN)之外,一切都是正确的。我一辈子都不知道为什么。我是一所大学的新生,这真让我头疼 import java.util.Scanner; public class ReimannSumCalculator { static double a,b,c,start,end; static double partitions; static double delta=e
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);
}
}
在初始化这些变量之前,您正在执行start/partitions
所以你实际上是在计算0.0/0.0,等于NaN。Java不是excel。它不会自动计算符号表达式的操作顺序,也不会在输入更改时重新计算表达式 获得正确的操作顺序,并在输入过时时重新计算值的负担由程序员承担
static double a,b,c,start,end;
static double partitions;
static double delta=end - start / partitions;
相当于
static double a,b,c,start = 0.0d, end = 0.0d;
static double partitions = 0.0d;
static double delta=end - start / partitions;
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
因为所有字段的类型都为零值,这相当于
static double a,b,c,start = 0.0d, end = 0.0d;
static double partitions = 0.0d;
static double delta=end - start / partitions;
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
因为字段是按照声明的顺序初始化的
然后你无法在main主体中重新计算delta,因此你最终将一个NaN的delta传递给leftReimann和rightReimann
使用整数循环来确保处理正确数量的分区,而不是比较双x和双边界,这可能是有意义的。浮点运算是有损的,所以在循环条件中检查double时可能会遇到边界条件
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;
}
有两种选择,要么使delta成为函数
private double getDelta() { return (end - start) / partitions;
或者,您可以在设置结束、开始或分区后重新计算增量。在这种情况下,在调用Reiman函数之前,您应该说:
delta = (end - start) / partitions;
因此,它使用了end、start和partitions的新值
正如其他人所说,在初始化delta时,分区为零,因此被零除为NaN。如果要发布一些代码,请花一些时间将其格式化为可读形式。请这一次我是为你做的,谢谢你的回答。这是有道理的。我通过在我的主方法中重新计算来修正我的delta值,但是,你知道为什么我的右Reimann和左Reimann和方法都返回零吗?@JustinTaylor,当你重新计算它时,什么是分区?如果分区很小,则可能会遇到边界问题@JustinTaylor,请参阅我的ammended注释re int循环。@JustinTaylor,另外end-start/partitions等同于end-start/partitions,因为除法的运算符优先级高于减法。它与您想要的结束-开始/分区不同。