1

I am trying to solve a complicated mathematical expression using Java on Netbeans, however I have two problems: "cannot find symbol (variable)", and the result I get is always 'NaN'.

But when I tried 'double x = 0;' instead of 'double x;' my code works but the answer I get is always 'NaN'. I also tried initializing the variable on scan 'double x = scan.nextDouble();' but it doesn't work either.

Then I realized the pattern that most of the code I type that involves complicated math, needs to have '= 0;' for the variables to be found by the compiler.

So my real question is, what is the difference between 'double x = 0;' and 'double x;' Why does the former work in mathematical expressions, but the latter can't be detected by the compiler?

Unnecessary Information Below

    //The code I made for my homework
    double ans, num, den, x, y;
    //double x = 0;
    //double y = 0;

    //variable x and y might not have been initialized
    num = Math.cbrt( ((2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) )) );
    den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));   

    ans = num / den;

    System.out.print("x: ");
    x = scan.nextDouble();
    System.out.print("y: ");
    y  = scan.nextDouble();
    System.out.println("\n The answer is " + ans); 

I have the mathematical expression of ((\root(3)((2x^(4)y+2xy^(4)) )))/(4xy^(2x+2y))

I expect the output of

x: 2 y: 3

The answer is 0.096157...

Instead, I get the result of 'variable x and y might not have been initialized' and on another scenario I get the result of 'The answer is NaN'. I'm thinking if I can use variables for each term to solve it.

EDIT: I SUCCESSFULLY MADE THE DIVISION OF THE 'DOUBLES' by removing the 'double x = 0;', I eliminated the possibility of 'NaN'. Instead, I declare and assign values to variables at the same time.

    System.out.print("x: ");
    double x = scan.nextDouble();
    System.out.print("y: ");
    double y  = scan.nextDouble();


    //preparation
    //double term1, term2, term3, term4, term5, term6, exp; //x, y;
    //double x = 0;
    //double y = 0;

    //variable x and y might not have been initialized
   //double term1 = (Math.cbrt(2 * Math.pow(x,4) * y));
   //double term2 = (Math.cbrt(2 * x * Math.pow(y,4)));
   //double term3 = (4 * x);
   //double term4 = (2 * x); 
   //double term5 = (2 * y);
  // double exp = term4 + term5;
   //double term6 = (Math.pow(y,exp)); 
   //double num = (Math.cbrt((2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y, 4))));
   //double den = term3 * term6; 
   double num = (2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) );
   double den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));


   double ans = Math.cbrt(num / den);

   System.out.println("\n The answer is " + ans);
tRanChor
  • 13
  • 4
  • double x = 0 is initialize variable where double x; depend on where its defined. inside method it become method local variable and have no initial value – SSP Sep 28 '19 at 07:17
  • NaN usually happens when you divide zero by zero. Cannot find symbol (variable) usually means you haven't declared the variable OR you have miss-spelled the name. – Stephen C Sep 28 '19 at 07:18
  • Might not have been initialized means that the Java compiler thinks there is an execution path through your program that doesn't initialize a (local) variable before it is (could be) used. – Stephen C Sep 28 '19 at 07:20

3 Answers3

1

Local variables must be given a value before they are referred to. Since your code executes from top to bottom, the calculations will be done before x and y are initialised to the user input values. This is why it says "variable might not be initialised" in your calculations.

Your misconception might be thinking that these lines define some kind of a "relationship" between x, y, num, den:

num = Math.cbrt( ((2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) )) );
den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));

ans = num / den;

But they actually don't. They simply do the calculations, and set the variable on the left hand side to the result. However, at this point, the values of x and y are not known yet, because the x = ... and y = ... lines haven't run yet.

What if you add double x = 0 and double y = 0 at the top? That solves the compiler error. The calculation can now be carried out, but it will use the x=0 and y=0. That's all the information it has got at that moment, as the lines where you get user input has not been run yet.

What you should do is to move the lines that read the user input before the calculations:

System.out.print("x: ");
x = scan.nextDouble();
System.out.print("y: ");
y  = scan.nextDouble();

num = Math.cbrt( ((2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) )) );
den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));

ans = num / den;
System.out.println("\n The answer is " + ans);

Also, to get the expected output of 0.096157..., you need the cube root to apply to the whole fraction, not just the numerator:

num = (2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) );
den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));

ans = Math.cbrt(num / den);
Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

So my real question is, what is the difference between double x = 0; and double x;

The former declares x and gives it an initial value.

The latter declares x and does not give it an initial value. You can give x a value later, but you must do this for all paths that lead to any use of the variable. For example:

double x;
if (Math.pow(2, 2) >= 0.0) {
    x = 0.0;
} else {
    x = 1.0;
}
System.out.println(x);   // OK

versus

double x;
if (Math.pow(2, 2) >= 0.0) {
    x = 0.0;
}
System.out.println(x);   // ERROR

The latter is a compilation error because there is a possible path through the code where x may be used before it has been initialized.

Now anyone with highschool maths knowledge can tell you that the square of an integer will always be greater or equal to zero, and therefore the else branch will never be taken. However the Java compiler doesn't know this, and will give you a compilation error. (Indeed, it is not permitted to not give you a compilation error. I won't go into the details: they are in the JLS if you care.)


Why does the former work in mathematical expressions, but the latter can't be detected by the compiler?

Now that is an interesting question.

The answer is that = has a fundamentally different meaning in programming languages and mathematical equations.

In a programming language like Java, a = b; means "assign (set) the current value of a to the current value of b".

In an mathematical equation a = b means "for all places where these a and b variables are used, the value of a is equal to the value of b.". It is basically a constraint on the possible values of a and b.

Another way to think about this is that in mathematics, a variable in an equation represents a set of possible values. The equation constrains the set of values; e.g. a = sqrt(4) is equivalent to saying that a denotes {x | x * x == 4} which is the same as the set {-2, +2}.

Now mathematics does have cases where the notation is erroneous. For example a = a + 1 is equivalent to saying that a denotes {x | x == x + 1} ... which is the empty set.

(The notation I used above is not what classical mathematicians and formal methods people would normally use. Unfortunately, it is rather difficult to explain this unless you have taken some University level Mathematics subjects / units. Or a formal methods units in a Computer Science course.)


Finally, here are so generic Q&A's that address your other compilation and runtime errors:

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • So variable declaration and initialization are different from each other. And the variable needs an initial value for each mathematical use. The compiler can't perceive mathematical relationships without an initial value that limits the set of possible numbers for each variable. – tRanChor Sep 29 '19 at 04:14
0

Local variables including primitives do not have default values assigned and need to be initialized explicitly. You have to set initial values for x and y, else the compiler protests.

Why must local variables, including primitives, always be initialized in Java?

Martin'sRun
  • 522
  • 3
  • 11