This question already has answers here:
What does the ^ operator do in Java?
(19 answers)
Closed 7 years ago.
So I'm new to Java and I have an assignment to do for class, but I'm stuck. The class is supposed to find the intersection of two lines using the quadratic equation. I was told to have specific inputs for class, so d = 5, f = -3, g = 2, m = 1 and b = 3 and the two intersections are supposed to be (1,4) and (-.20,2.8). The problem I'm running into is that the output returns (NaN,NaN) and (NaN,NaN) instead of the right answer. Is there anything wrong with my code that is making me get this answer?
public class Intersect{
public static void main(String args[]){
//prompt user for parabola vars d f g
System.out.println("Enter the constant d:");
int d = IO.readInt();
System.out.println("Enter the constant f:");
int f = IO.readInt();
System.out.println("Enter the constant g:");
int g = IO.readInt();
// y = dx^2 + fx + g
//promt user for line vars m b
System.out.println("Enter the constant m:");
int m = IO.readInt();
System.out.println("Enter the constant b:");
int b = IO.readInt();
// y = mx + b
//compute intersection
// dx^2 + fx + g = mx + b
// x^2 * (d) + x * (f-m) + (g-b) = 0
int a = d;
int z = (f-m);
int c = (g-b);
double x1 = -z + (Math.sqrt (z^2 - 4 * a * c) / (2 * a));
double x2 = -z - (Math.sqrt (z^2 - 4 * a * c) / (2 * a));
double y1 = m * x1 + b;
double y2 = m * x2 - b;
//output each intersection on its own line, System.out.println() is ok for this answer submission
System.out.println("The intersection(s) are:");
System.out.println("(" + x1 + "," + y1 + ")");
System.out.println("(" + x2 + "," + y2 + ")");
}
}
^ is the xor operator in java and not the exponentiation operator. Therefore, the expresson z ^ 2 - 4 * a * c computes to something negative.
From the input you provide, z = -4, a = 5, c = -1. The expression translates to -4 ^ 2 - 4 * 5 * -1. Note that * and + have a higher precedence than ^, i.e. the order of evaluation is (-4 ^ (2 - ((4 * 5) * -1))) = -22.
Then you're trying to find the square root of -22, which, according to Math.sqrt(), is NaN.
Use Math.pow(z, 2), or simply use z * z instead:
Math.sqrt(z * z - 4 * a * c); // Note: This time operator precedence works,
// But you should use parentheses wherever
// the expression seems ambiguous.
First of all ^ is not an exponentiation operator, what causes Nan is the fact that you pass in a negative argument to Math.sqrt.
From java reference ( http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html ):
public static double sqrt(double a)
Returns the correctly rounded positive square root of a double value. Special cases:
If the argument is NaN or less than zero, then the result is NaN.
If the argument is positive infinity, then the result is positive infinity.
If the argument is positive zero or negative zero, then the result is the same as the argument.
Otherwise, the result is the double value closest to the true mathematical square root of the argument value.
Parameters:
a - a value.
Returns:
the positive square root of a. If the argument is NaN or less than zero, the result is NaN.
Its your order of operations that is causing you to get NaN results.
Try this(added variables for convenience):
int a = d;
int z = f - m;
int negZ = -z;
int c = g - b;
double sq = Math.sqrt((z * z) - (4 * a * c));
double a2 = 2 * a;
double x1 = (negZ + sq) / a2;
double x2 = (negZ - sq) / a2;
double y1 = (m * x1) + b;
double y2 = (m * x2) - b;
Related
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);
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);
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:
What does a "Cannot find symbol" compilation error mean?
Variable might not have been initialized error
In Java, what does NaN mean?
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?
How to make the method roots check imaginary roots and real one then return their values?
package warmup;
import java.util.HashSet;
import java.util.Set;
public class Quadratic {
/**
* Find the integer roots of a quadratic equation, ax^2 + bx + c = 0.
* #param a coefficient of x^2
* #param b coefficient of x
* #param c constant term. Requires that a, b, and c are not ALL zero.
* #return all integers x such that ax^2 + bx + c = 0.
*/
public static Set<Integer> roots(int a, int b, int c) {
Set<Integer> z = new HashSet<>();
int temp1 = (int)(Math.sqrt(b*b - 4*a*c));
if(a !=0){
if(temp1 >= 0){
Integer x1 = (int) ((-b + temp1) / (2*a));
Integer x2 = (int) ((-b - temp1) / (2*a));
z.add(x1);
z.add(x2);
} else if (temp1 < 0){
Integer x1 = (int) ((-b + temp1) / (2*a));
Integer x2 = (int) ((-b - temp1) / (2*a));
z.add(x1);
z.add(x2);
}
}else{
System.out.println("Error: division by zero.");
}
return z;
}
/**
* Main function of program.
* #param args command-line arguments
*/
public static void main(String[] args) {
System.out.println("For the equation x^2 - 4x + 3 = 0, the possible solutions are:");
Set<Integer> result = roots(1, -4, 3);
System.out.println(result);
}
trying to assign a negative square root number value to java is not allowed in JDK.
what you can do is, you can create a complex number class of your own and do your own operations there. Here is the example which i found online:
http://introcs.cs.princeton.edu/java/97data/Complex.java.html
I also looked at SO for similar questions like yours and i got this link
Hope this helps
I saw someone else posted this problem but didn't word it properly so he didn't end up receiving any help, so I figured I would try and be more direct.
Here is the problem proposed to us :
// Write and submit your code in a file called Intersect.java. Use the IO module to read inputs. Use System.out.println() to print your answer.
Write a program that calculates the intersection between 2 equations:
a degree-2 (quadratic) polynomial i.e.
y = dx^2 + fx + g
where d, f, and g are constants
and a degree-1 (linear) equation i.e.
y = mx + b
where m is the slope and b is a constant
The above is just text, not code that could appear in a Java program.
Ask the user for the constant values in each equation. Output the intersection(s) as ordered pair(s) (x,y), or "none" if none exists. Below is an example run.
java Intersect
Enter the constant d:
5
Enter the constant f:
-3
Enter the constant g:
2
Enter the constant m:
1
Enter the constant b:
3
The intersection(s) is/are:
(1,4)
(-0.20,2.8)
//
The main problem is essentially asking us to write a code that asks the user to imput the individual constants and the slope of the two equations, one being a quadratic polynomial and the other being a linear equation in point-slope.
I understand that we have to use the quadratic equation in the code, however I have no idea how to actually code this in.
Once we have had the user imput the constants, in this case 5 (d,f,g,m,b; with m being slope) we need to have the code run the calculations to imput those constants into the above example ( y = dx^2 + fx + g | y = mx + b) and return either "none" if there is no intersection, or if it does intersect, the ordered pair at which it does intersect (x,y).
I know already that if 0 is entered as the constants it returns (NaN,NaN) which I also know needs to be re-written to None.
so far I only have the following:
public class Intersect {
public static void main(String[] args) {
System.out.println("Enter the constant d:");
int d = IO.readInt();
System.out.println("Enter the constant f:");
int f = IO.readInt();
System.out.println("Enter the constant g:");
int g = IO.readInt();
System.out.println("Enter the constant m:");
int m = IO.readInt();
System.out.println("Enter the constant b:");
int b = IO.readInt();
If anyone can shed some light on this that would be fantastic, thanks!
EDIT1 :
So far i've changed the code to the following, however, I still don't know how to get it to return to me an answer:
public class Intersect {
public static void main(String[] args) {
System.out.println("Enter the constant d:");
int d = IO.readInt();
System.out.println("Enter the constant f:");
int f = IO.readInt();
System.out.println("Enter the constant g:");
int g = IO.readInt();
System.out.println("Enter the constant m:");
int m = IO.readInt();
System.out.println("Enter the constant b:");
int b = IO.readInt();
//y = dx^2 + fx + g
//y = mx + b
//mx + b = dx^2 + fx + g
//x^2 * (d) + x * ( f - m ) + ( g - b )
int A = d;
int B = f - m;
int C = g - b;
double x1 = - B + Math.sqrt( B^2 - 4 * A * C ) / (2 * A);
double x2 = - B - Math.sqrt( B^2 - 4 * A * C ) / (2 * A);
double y1 = m * x1 + b;
double y2 = m * x1 + b;
}
Also, eclipse is telling me that x2,y1, and y2 aren't used at all.
I know I need to use System.out.println() however I don't understand what I can put there to make the answer an ordered pair. Also, I tried setting an If statement to have the answer return None instead of NaN however it instead returns, NaN None.
There are a lot of special cases you have to take into account.
I hope I've got them all right.
So after the initialization of the values you can put this:
// calculating some useful values.
double t = -(f - m) / (2.0 * d);
double u = t * t - (g - b) / (double) d;
// the first polynomial is linear, so both terms are.
if (d == 0) {
// both linear functions have the same slope.
if (f == m) {
// both functions are shifted the same amount along the y-Axis.
if (g == b)
// the functions lie on top of each other.
System.out.println("There is an infinite amount intersections");
// the functions are shifted different amounts along the y-Axis.
else
// the lines are parallel.
System.out.println("There are no intersections");
}
// both linear functions have different slopes.
else {
// solve linear equation.
double x = (b - g) / (double) (f - m);
double y = m * x + b;
System.out.println("The intersection is: (" + x + "," + y + ")");
}
}
// the functions do not cross each other.
else if (u < 0)
System.out.println("There are no intersections");
// the linear function is a tangent to the quadratic function.
else if (u == 0) {
// solve equation.
double x = t;
double y = m * x + b;
System.out.println("The intersection is: (" + x + "," + y + ")");
}
// the linear function intersects the quadratic function at two points.
else {
// solve quadratic equation.
double x1 = t + Math.sqrt(u);
double x2 = t - Math.sqrt(u);
double y1 = m * x1 + b;
double y2 = m * x2 + b;
System.out.println("The intersections are: (" + x1 + "," + y1 + ") (" + x2 + "," + y2 + ")");
}
i guess....
//y = dx^2 + fx + g
//y = mx + b
//mx + b = dx^2 + fx + g
//x^2 * (d) + x * ( f - m ) + ( g - b )
A = d
B = f - m
C = g - b
x1 = - B + sqr( B^2 - 4 * A * C ) / (2 * A)
x2 = - B - sqr( B^2 - 4 * A * C ) / (2 * A)
y1 = m * x1 + b
y2 = m * x1 + b
My code:
int a = 1;
int b = 6;
int c = 5;
double x1 = (-b + Math.sqrt(b^2 - 4*a*c))/(2*a);
double x2 = (-b - Math.sqrt(b^2 - 4*a*c))/(2*a);
System.out.println("x=" + x1 + x2 );
Output:
x=NaNNan
b^2 doesn't do what you think it does in Java. Write b*b instead. The ^ operator is actually the bitwise-XOR operator; there is no exponent operator. (There is, however, a Math.pow() function.)
In addition to ^ being a XOR instead of the power, your solver has another issue: sometimes, B2 is less than 4AC, in which case the equation has only complex solutions. Your code should check for that condition before calling Math.sqrt to avoid getting a NaN back.
Finally, your output is incorrect: your println would produce the concatenation of the roots with no space in between, rather than printing them individually.
Here is your code after the fix:
int a = 1;
int b = 6;
int c = 5;
int d = b*b - 4*a*c;
if (d < 0) {
System.out.println("No real solutions.");
} else {
double sqD = Math.sqrt(d);
double x1 = (-b + sqD)/(2*a);
double x2 = (-b - sqD)/(2*a);
System.out.println("x=" + x1 + " " + x2 );
}
You could write b * b or Math.pow(b,2) instead of b ^ 2, which is the bitwise xor (exclusive or) of b with 2.
It looks like you're trying to make a trigonometric function here. Dont remember the name but i can tell that b is meant to be squared? If so, use the Math.pow(numberToSquare, theSquareNumber)
The one line Will look like this:
Double x1 = (-b + Math.sqrt(Math.pow(b, 2) - 4*a*c))/(2*a)
This quadratic equation will not return negative numbers in the string that I've determined it to return.
Here's the equation:
public class QuadraticEquation {
String final0;
public String calculate(int a, int b, int c) {
double done1 = ((-1 * b) + Math.sqrt((b * b) - (4 * a * c))) / (2 * a);
double done2 = ((-1 * b) - Math.sqrt((b * b) - (4 * a * c))) / (2 * a);
final0 = "x = " + (done1) + " or x = " + (done2);
return final0;
}
}
imagine an equation with a, b, and c values like -3, 13, and -4. The returning value of this would be -0.3(repeating) and -4. But this equation only returns positives, so in this case it would return 0.3(repeating) and 4. Why is this, and what can I do to fix it?
Note: I do believe that this is a Java error and not a math error. If it is a math error, let me know in the comments and I will promptly put it in the proper forums. Thanks.
public static void main(String[] args) {
String final0 = calculate(-3, 13, -4);
System.out.println(final0);
}
public static String calculate(int a, int b, int c) {
String final0 ;
int i = -1 * b; // -1 * 13 = -13
System.out.println(i);
int j = 4 * a * c; // 4 * -3 * -4 = 4 * 12 = 48
System.out.println(j);
double sqrt = Math.sqrt((b * b) - j); // sqrt ((13 * 13) - 48) = sqrt(169 - 48) = sqrt(121) = 11
System.out.println(sqrt);
double d = i + sqrt; // -13 + 11 = -2
System.out.println(d);
int k = 2 * a; // 2* -3 = -6
System.out.println(k);
double done1 = d / k; // -2 / -6 = 1/3 = 0.3333333333
System.out.println(done1);
double done2 = (i - sqrt) / k;
final0 = "x = " + (done1) + " or x = " + (done2);
return final0;
}
If you decompose your method to more local variables, you will see that math in java works correctly.
I would have thought
-3*x^2 + 13 *x + -4 = -3 * (x - 0.33333) * (x - 4) = 0
so two positive answers is correct.
Try instead
1 * x^2 + 0 * x -1 = (x - 1) * (x + 1) = 0
i.e. x = -1 or +1
Here is how I would write it.
public static String calculate(int a, int b, int c) {
double sqrt = Math.sqrt((b * b) - (4 * a * c));
double done1 = (-b + sqrt) / (2 * a);
double done2 = (-b - sqrt) / (2 * a);
return "x = " + (done1) + " or x = " + (done2);
}
The code is working correctly with your input. If you changed b to be -13 for example, you would get
x = -4.0 or x = -0.3333333333333333
Math.sqrt will always return a positive number ignoring complex numbers. But that is somewhat besides the point.