I have posted this question before. But have made a huge edit to it. And would like to ask for help in correcting my steps since my java code is not compiling.
write a method printRoots that given 3 terms as input, representing a,b, and c in that order prints their roots.
We have the following given information
**If b²-4ac is a positive number, your program should print “The two roots are X and Y” where X is the larger root and Y is the smaller root
If b²-4ac equals 0, the program should print. “The equation has one X” where X is the only root
If b²-4ac is a negative number, the program should print.” The equation has two roots(-X1 + Y1i) and (-X2 and Y2i)**
The term can be determined based on:
If b^2 - 4ac is a negative number, then the quadratic equation becomes: (-b+/- √C)/2a -This means the equation can be simplified to become (-b+/- √Ci)/2a where the square root is not a positive number
Calculate the coefficient and print that(i.e X1 is -b/2a and Y1 is sqrt(-C)/2i)
Note: Not allowed to use Scanners for this question
Is it possible for someone to review my program and tell me where I have gone wrong and do i just remove my scanners to make it a program without scanners? How do i enter a,b,c then??
Give note: you should NOT use Scanner inside this method. To test your method you can use SCanner in the main method OR you can hard code values into your code from the main method and then call the method printRoots with those inputs or ouputs.
import java.util.Scanner;//delete this part after
public class findingRoots {
public static void main(String[] args)
{
}
public static double printRoots (){ //should it be double here or int?
//read in the coefficients a,b,and c
Scanner reader = new Scanner(System.in);
System.out.println("Enter the value of a");
int a=reader.nextInt();
System.out.println("Enter the value of b");
int b=reader.nextInt();
System.out.println("Enter the value of c");
int c=reader.nextInt();
//now compte the discrimintat d
double discriminant = (Math.pow(b, 2.0)) - (4 * a * c);
d=Math.sqrt(discriminant);
double X,Y; //root 1 & root 2, respectively
// is the step double X,Y necessary?
double d = (b*b)-(4.0*a*c);
if (discriminant > 0.0){
X = (-b + d)/(2.0 * a ); //X= root 1, which is larger
**//do i put int or double in front of X?**
Y = (-b - d)/(2.0 *a); //Y= root 2, which is the smaller root
String root1 = Double.toString(X)
String root2 = Double.toString(Y)
System.out.println("The two roots are X and Y:" + root1 + "and" + root2);
}
else{
if (discriminant==0.0)
X = (-b + 0.0)/(2.0 * a);//repeated root
String root2 = Double.toString(X)
System.out.println("The equation has one root X:" + root1);//where X is the only root
}
if(discriminant < 0.0){
X1 = -b/(2*a);
Y1 = (Math.sqrt(-C))/(2*a);
X2 = -b/(2*a);
Y2 = (-(Math.sqrt(-C)))/(2*a);
String root1 = Double.toString(X1)
String root2 = Double.toString(Y1)
String root3 = Double.toString(X2)
String root4 = Double.toString(Y2)
System.out.println("The equation has two roots:" + (root1 + (root2)"i") "and" + (root3 + (root4)"i");
// where i represents the square root of negative 1
}
}
}
Ok, so there a quite a bit wrong with the code. Here is a running version of your program. (or at least as close as I can get to what you are trying to do).
//import java.util.Scanner;//delete this part after
public class findingRoots {
public static void main(String[] args) {
double temp = printRoots(Integer.parseInt(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]));
}
public static double printRoots (int a, int b, int c){ //should it be double here or int?
//read in the coefficients a,b,and c
//now compte the discrimintat d
double discriminant = (Math.pow(b, 2.0)) - (4 * a * c);
double d=Math.sqrt(discriminant);
double X = 0,Y = 0; //root 1 & root 2, respectively
// is the step double X,Y necessary?
d = (b*b)-(4.0*a*c);
if (discriminant > 0.0) {
X = (-b + d)/(2.0 * a ); //X= root 1, which is larger
//do i put int or double in front of X?**
Y = (-b - d)/(2.0 *a); //Y= root 2, which is the smaller root
String root1 = Double.toString(X);
String root2 = Double.toString(Y);
System.out.println("The two roots are X and Y:" + root1 + "and" + root2);
}
else if (discriminant==0.0){
X = (-b + 0.0)/(2.0 * a);//repeated root
String root2 = Double.toString(X);
System.out.println("The equation has one root X:" + root2);//where X is the only root
}
else if (discriminant < 0.0){
double X1 = -b/(2*a);
double Y1 = (Math.sqrt(-c))/(2*a);
double X2 = -b/(2*a);
double Y2 = (-(Math.sqrt(-c)))/(2*a);
String root1 = Double.toString(X1);
String root2 = Double.toString(Y1);
String root3 = Double.toString(X2);
String root4 = Double.toString(Y2);
System.out.println("The equation has two roots:" + root1 + root2 + "and" + root3 + root4);
// where i represents the square root of negative 1
}
return -1;
}
}
To run this code simply type:
java findingRoots 1 2 3 where 1 2 3 are your a, b, c values respectively.
This is not working the way you want it to (i assume). This should get you a start as to trouble shooting though as it can now run. Let's see what you can do from here.
Related
I've been trying a lot but it only shows NaN. I'm not sure if I'm doing the right thing.
class Imaginary{
double a = 2;
double b = 3;
double c = 5;
double result = b * b - 4 * a * c;
if(result < 0.0){
double im1 = -2 + (Math.sqrt((result))/ 10);
double im2 = -2 - (Math.sqrt((result))/ 10);
System.out.println("x = " + imaginary1 + " or x = " + imaginary2);
}
}
You need to take negate result to make it positive before taking the square root (taking square roots of negative numbers always results in NaN) and append "i" before printing.
double real = -b / (2*a);
double img = Math.sqrt(-result) / (2*a);
System.out.println("x = " + real + " + " + img +"i or x = " + real + " - " + img + "i");
You shouldn't use sqrt(result) since it will always result in you taking the square root of a negative number (that is your condition for result). Instead try to use a formula (eg completing the square).
Hope it answers your question :)
Since you have a complex root, you need to work with complex numbers to solve the equation. Java lacks builtin support for complex numbers, but you can e.g. use Apache Commons:
if (result < 0.0) {
final Complex cb = new Complex(-b, 0.0);
final Complex root = new Complex(result, 0.0).sqrt();
final Complex r1 = cb.add(root).divide(2 * a);
final Complex r2 = cb.subtract(root).divide(2 * a);
}
Solving a quadratic equation
I have the following written down so far. I am not sure on how to introduce the second method
public static void main(string args[]){
}
public static double quadraticEquationRoot1(int a, int b, int c) (){
}
if(Math.sqrt(Math.pow(b, 2) - 4*a*c) == 0)
{
return -b/(2*a);
} else {
int root1, root2;
root1 = (-b + Math.sqrt(Math.pow(b, 2) - 4*a*c)) / (2*a);
root2 = (-b - Math.sqrt(Math.pow(b, 2) - 4*a*c)) / (2*a);
return Math.max(root1, root2);
}
}
Firstly, your code won't compile--you have an extra } after the start of public static double quadraticEquationRoot1(int a, int b, int c) ().
Secondly, you aren't looking for the correct input types. If you want input of type double, make sure you declare the method appropriately. Also be careful of declaring things as int when they could be doubles (for example, root1 and root2).
Thirdly, I don't know why you have the if/else block--it would be better to simply skip it, and only use the code that is currently in the else part.
Finally, to address your original question: Simply create a separate method and use Math.min() instead of Math.max().
So, to recap in code:
public static void main(string args[]){
}
//Note that the inputs are now declared as doubles.
public static double quadraticEquationRoot1(double a, double b, double c) (){
double root1, root2; //This is now a double, too.
root1 = (-b + Math.sqrt(Math.pow(b, 2) - 4*a*c)) / (2*a);
root2 = (-b - Math.sqrt(Math.pow(b, 2) - 4*a*c)) / (2*a);
return Math.max(root1, root2);
}
public static double quadraticEquationRoot2(double a, double b, double c) (){
//Basically the same as the other method, but use Math.min() instead!
}
Well why don't you try to use the same exact algorithms but then use Math.min in your return statement?
Also, note that you're not taking into account whether or not $b$ is negative in your first if statement. In other words you simply return $-b / 2a$ but you don't check if $b$ is negative, if it isn't then this is actually the smaller of the two roots not the larger.
Sorry about that! I misinterpreted what was going on xD
package QuadraticEquation;
import javax.swing.*;
public class QuadraticEquation {
public static void main(String[] args) {
String a = JOptionPane.showInputDialog(" Enter operand a : ");
double aa = Double.parseDouble(a);
String b = JOptionPane.showInputDialog(" Enter operand b : ");
double bb = Double.parseDouble(b);
String c = JOptionPane.showInputDialog(" Enter operand c : ");
double cc = Double.parseDouble(c);
double temp = Math.sqrt(bb * bb - 4 * aa * cc);
double r1 = ( -bb + temp) / (2*aa);
double r2 = ( -bb -temp) / (2*aa);
if (temp > 0) {
JOptionPane.showMessageDialog(null, "the equation has two real roots" +"\n"+" the roots are : "+ r1+" and " +r2);
}
else if(temp ==0) {
JOptionPane.showMessageDialog(null, "the equation has one root"+ "\n"+ " The root is : " +(-bb /2 * aa));
}
else{
JOptionPane.showMessageDialog(null, "the equation has no real roots !!!");
}
}
}
Okay so I am a complete Java noob, and I'm trying to create a program for class that runs a quadratic equation using scanner inputs. So far what I've got is this:
import java.util.*;
public class QuadraticFormulaSCN {
public static void main(String[]args) {
System.out.println("insert value for a:");
Scanner scan1 = new Scanner(System.in);
double a = scan1.nextDouble();
System.out.println("insert value for b:");
Scanner scan2 = new Scanner(System.in);
double b = scan2.nextDouble();
System.out.println("insert value for C:");
Scanner scan3 = new Scanner(System.in);
double c = scan3.nextDouble();
double answer =((Math.sqrt(Math.pow(b,2)-(4*a*c))-b)/2);
double final2 =(-b + Math.sqrt(Math.pow(b,2)-(4*a*c)))/2;
System.out.println("The x values are:" + answer + final2);
}
}
But I get a weird output, specifically NaNaN... What do I do to fix this? What am I doing wrong?
I'm a little late to answer, but I corrected your problems (described in the other answers), fixed one of your calculations, and cleaned up your code.
import java.util.*;
public class Test {
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
System.out.println("Insert value for a: ");
double a = Double.parseDouble(s.nextLine());
System.out.println("Insert value for b: ");
double b = Double.parseDouble(s.nextLine());
System.out.println("Insert value for c: ");
double c = Double.parseDouble(s.nextLine());
s.close();
double answer1 = (-b + Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a);
double answer2 = (-b - Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a);
if (Double.isNaN(answer1) || Double.isNaN(answer2))
{
System.out.println("Answer contains imaginary numbers");
} else System.out.println("The values are: " + answer1 + ", " + answer2);
}
}
NaN is something you get when the calculation is invalid. Such as dividing by 0 or taking the squareroot of -1.
When I test your code with a = 1, b = 0 and c = -4 the answers is 2.02.0
The formatting is not right and the calculation of final2 is not negated.
Otherwise the code is right.
To improve you could check whether the discriminant is negative.
double d = b*b -4 * a * c;
if (d < 0){
System.out.println("Discriminant < 0, no real solutions" );
return;
}
double x1 = (-b -sqrt(d))/(2*a);
double x2 = (-b +sqrt(d))/(2*a);
System.out.format("The roots of your quadratic formula are %5.3f and %5.3f\n",x1,x2);
Or, if you prefer support for solutions from the complex domain:
if (d < 0) {
System.out.println("Discriminant < 0, only imaginary solutions");
double r = -b / (2 * a);
double i1 = -sqrt(-d) / (2 / a);
double i2 = sqrt(-d) / (2 / a);
System.out.format("The roots of your quadratic formula are (%5.3f + %5.3fi) and (%5.3f + %5.3fi)\n",r, i1, r, i2);
return;
}
You are getting NaN because you are attempting to take the square root of a negative number. In math that's not allowed unless you are allowing complex numbers, e.g. 1 +/- 2i.
This can happen in quadratic formulas when the discriminant (the thing in the square root) is negative, e.g. x^2 + 6*x + 100: b^2 - 4ac = 36 - 400 = -364. Taking the square root of a negative number in Java leads to NaN. (not a number)
To test for NaN, use Double.isNaN and handle the NaN appropriately.
In addition, your calculations are incorrect even if NaN isn't being encountered:
$ java QuadraticFormulaSCN
insert value for a:
1
insert value for b:
5
insert value for C:
6
The x values are:-2.0-2.0
This should have outputted 2.0 and 3.0
You should only do the calculation when
discriminant is equal or greater than zero
if(((Math.pow(b,2)-(4*a*c))>= 0){ /* Calculation here */ }
else {/*error message or complex number calculus*/};
One thing I always try to do is put all my math in appropriate parenthesis to avoid an, all too easy, Order of Operations mistake. The NaN is saying "Not a number." You would also get that message if the user input numbers that could not produce a result, such as a trying to get the square root of a negative number. Also, just as a note, you can save sometime by only using on Scanner for a,b, and c.
public class QuadraticFormula{
public static void main(String[] args){
java.util.Scanner input = new java.util.Scanner(System.in);
double a = input.nextDouble();
double b = input.nextDouble();
double c = input.nextDouble();
double quadPos = (-b + Math.sqrt(Math.pow(b,2)-(4*a*c)))/(2*a);
double quadNeg = (-b - Math.sqrt(Math.pow(b,2)-(4*a*c)))/(2*a);
System.out.println("-b - = " + quadNeg + "\n-b + = " + quadPos);
}
}
This is the code that I have thus far. The goal of the project is to have the user enter any integers for a, b, c for the ax^2+bx+c equation. For some reason I am not getting the correct roots for any numbers that are input into the program. Can anyone point out my wrong doings?
import java.util.*;
public class Quad_Form {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
double a = 0;
double b = 0;
double c = 0;
double discrim = 0;
double d = 0;
System.out.println("Enter value for 'a'");
String str_a = sc.nextLine();
a = Integer.parseInt(str_a);
System.out.println("Enter value for 'b'");
String str_b = sc.nextLine();
b = Integer.parseInt(str_b);
System.out.println("Enter value for 'c'");
String str_c = sc.nextLine();
c = Integer.parseInt(str_c);
double x1 = 0, x2 = 0;
discrim = (Math.pow(b, 2.0)) - (4 * a * c);
d = Math.sqrt(discrim);
if(discrim == 0){
x1 = (-b + d) / (2* a);
String root_1 = Double.toString(x1);
System.out.println("There is one root at: " + root_1);
}
else {
if (discrim > 0)
x1 = (-b + d) / (2 * a);
x2 = (-b - d) / (2 * a);
String root_1 = Double.toString(x1);
String root_2 = Double.toString(x2);
System.out.println("There are two real roots at:" + root_1 + "and" + root_2);
}
if (discrim < 0){
x1 = (-b + d) / (2 * a);
x2 = (-b - d) / (2 * a);
String root_1 = Double.toString(x1);
String root_2 = Double.toString(x2);
System.out.println("There are two imaginary roots at:" + root_1 + "and" + root_2);
}
}
}
#Smit is right about one of the issues, but there's a second one as well.
Math.sqrt(discrim) won't work when discrim is negative. You should be taking Math.sqrt(Math.abs(discrim)) instead.
a, b, c, d are double and you are parsing them as Integer. So this could be one of problem.
Use
Double.parseDouble();
Another problem is you can not make square root of negative numbers. This will result in NaN. For that use following, but you should handle that properly to get exact result.
Math.sqrt(Math.abs());
Moreover you should use following formula for getting roots
Taken from Wikipedia Quadratic equation
Class Double
Class Math
I'm new to Java and I've been trying to implement an algorithm for finding the roots of a cubical equation. The problem arises when I calculate the discriminant and try to check where it falls relative to zero.
If you run it and enter the numbers "1 -5 8 -4", the output is as follows:
1 -5 8 -4
p=-0.333333, q=0.074074
disc1=0.001372, disc2=-0.001372
discriminant=0.00000000000000001236
Discriminant is greater than zero.
I know the problem arises because the calculations with doubles are not precise. Normally the discriminant should be 0, but it ends up being something like 0.00000000000000001236.
My question is, what is the best way to avoid this? Should I check if the number falls between an epsilon neighborhood of zero? Or is there a better and more precise way?
Thank you in advance for your answers.
import java.util.Scanner;
class Cubical {
public static void main(String[] args) {
// Declare the variables.
double a, b, c, d, p, q, gamma, discriminant;
Scanner userInput = new Scanner(System.in);
a = userInput.nextDouble();
b = userInput.nextDouble();
c = userInput.nextDouble();
d = userInput.nextDouble();
// Calculate p and q.
p = (3*a*c - b*b) / (3*a*a);
q = (2*b*b*b) / (27*a*a*a) - (b*c) / (3*a*a) + d/a;
// Calculate the discriminant.
discriminant = (q/2)*(q/2) + (p/3)*(p/3)*(p/3);
// Just to see the values.
System.out.printf("p=%f, q=%f\ndisc1=%f, disc2=%f\ndiscriminant=%.20f\n", p, q, (q/2)*(q/2), (p/3)*(p/3)*(p/3), (q/2)*(q/2) + (p/3)*(p/3)*(p/3));
if (discriminant > 0) {
System.out.println("Discriminant is greater than zero.");
}
if (discriminant == 0) {
System.out.println("Discriminant is equal to zero.");
}
if (discriminant < 0) {
System.out.println("Discriminant is less than zero.");
}
}
}
The simplest epsilon check is
if(Math.abs(value) < ERROR)
a more complex one is proportional to the value
if(Math.abs(value) < ERROR_FACTOR * Math.max(Math.abs(a), Math.abs(b)))
In your specific case you can:
if (discriminant > ERROR) {
System.out.println("Discriminant is greater than zero.");
} else if (discriminant < -ERROR) {
System.out.println("Discriminant is less than zero.");
} else {
System.out.println("Discriminant is equal to zero.");
}
Should I check if the number falls between an epsilon neighborhood of
zero?
Exactly
Here's solution that is precise when the input values are integers, though it is probably not the most practical.
It will probably also work fine on input values that have a finite binary representation (eg. 0.125 does, but 0.1 doesn't).
The trick: Remove all divisions from the intermediate results and only divide once at the end. This is done by keeping track of all the (partial) numerators and denominators. If the discriminant should be 0 then it's numerator will be 0. No round-off error here as long as values at intermediate additions are within a magnitude of ~2^45 from each other (which is usually the case).
// Calculate p and q.
double pn = 3 * a * c - b * b;
double pd = 3 * a * a;
double qn1 = 2 * b * b * b;
double qd1 = 27 * a * a * a;
double qn2 = b * c;
double qn3 = qn1 * pd - qn2 * qd1;
double qd3 = qd1 * pd;
double qn = qn3 * a + d * qd3;
double qd = qd3 * a;
// Calculate the discriminant.
double dn1 = qn * qn;
double dd1 = 4 * qd * qd;
double dn2 = pn * pn * pn;
double dd2 = 27 * pd * pd * pd;
double dn = dn1 * dd2 + dn2 * dd1;
double dd = dd1 * dd2;
discriminant = dn / dd;
(only checked on the provided input values, so tell me if something's wrong)
maybe BigDecimal is worth a look at...
http://download.oracle.com/javase/1.4.2/docs/api/java/math/BigDecimal.html
you can secify the round mode in the divide-operation