2

I'm trying to solve exercise from Art & Science of Java, solution for quadratic equation.

import acm.program.*;

public class QuadraticEquation extends ConsoleProgram {
  public void run(){
    println("Enter coefficients for quadratic equation");
    int a = readInt("Enter first number: ");
    int b = readInt("Enter second number: ");
    int c = readInt("Enter third number: ");

    double result = quadratic(a,b,c);

    println("The first solution is: " + result);
  }

  private double quadratic(int a, int b, int c){
    double underSquare = (b*b-4*a*c);
    double x = (-b+Math.sqrt(b*b-(4*a*c)))/(2*a);
    if (underSquare < 0) {
        return null;
    } else {
      return (x);
    }
  }
}

I have an error in line: return null; saying:

Type mismatch: cannot convert from null to double

I don't really understand what this error, how should I solve this correctly?

Emil Sit
  • 22,894
  • 7
  • 53
  • 75

5 Answers5

5

You need to understand the difference between primitive types (e.g., double) and boxed object types (e.g., capital-D Double). Whereas Double is a reference to an object (and hence can be null), double is a primitive and can not be null.

The compiler is telling you that you declared the return type of your function to be double and so null can not be converted to a double.

Of course you could "fix" the problem by changing the return type to Double (which would make the null return legal, and cause your primitive doubles to be auto-boxed into Doubles) but that would not really serve you well. You want a better error handling strategy (of which there are many ... some possibilities are to throw an exception, use an Optional return type, use a flag value such as not-a-number aka Double.NaN).

Community
  • 1
  • 1
Emil Sit
  • 22,894
  • 7
  • 53
  • 75
2

You are asserting that the method should return a primitive of type double, instead you are returning a null value, which doesn't match the stated contract of the method.

What you want to do here depends entirely on how you want to catch this kind of error and there are a number of different solutions here that would be correct, but throwing a null object isn't one of them.

It's also worth noting that in your shown example:

double underSquare = (b*b-4*a*c);
double x = (-b+Math.sqrt(b*b-(4*a*c)))/(2*a);
if (underSquare < 0) {
    return null;
} else {
  return (x);
}

should be:

double underSquare = (b*b-4*a*c);
double x = (-b+(Math.sqrt(underSquare)))/(2*a);
return x;

which is equivalent to:

double underSquare = (b*b-4*a*c);
double x = (-b+Math.sqrt(b*b-(4*a*c)))/(2*a);
if (underSquare < 0) {
    return double.NaN;
} else {
  return (x);
}

but far more readable.

Java is smart enough to know that it shouldn't be taking the square root of a negative number and so if you just return x in both cases the code should run just fine. That said, you should also try to catch any exception here. Since there are a lot of error that could occur in directly evaluating numbers you should try something of this sort:

double underSquare = (b*b-4*a*c);
try{
    double x = (-b+(Math.sqrt(underSquare)))/(2*a);
} catch (Exception e){
    throw e;
} finally {
    return x
}
return x;
Slater Victoroff
  • 21,376
  • 21
  • 85
  • 144
0

Why do you check for negative determinant after you take the square root? That makes no sense. Check before you do it.

You return a single double, in spite of the fact that quadratics have two roots. What about the one you don't return?

In that case the results are two complex conjugate roots. You could certainly write a Complex class and return both roots.

You don't check for special cases (e.g. a = 0, b = 0, c =0). You should.

Your equation is implemented in the naive style, ignoring numerical issues.

Bad implementation. Lots of room for improvement.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • While this is all good advice, it does nothing to answer the question. You should point out that the error is that a `double` cannot be `null` since it is a primitive data type, as the other answers have pointed out. – wlyles Jun 28 '13 at 18:03
  • Yes, I know , will try my best. –  Jun 28 '13 at 18:14
  • I would say that telling the OP to move the check is very much an answer to the question. If the discriminant is negative, perhaps some indicator value should be returned. Answers on SO aren't always addressed to the OP. They live on long after s/he's gone. – duffymo Jun 28 '13 at 20:09
0

Since you seem to will to compute the real solutions of the equation you should probably consider throwing an exception.

You cannot return null because it can be used only with references while you want to return a double, which is a primitive data type

mariosangiorgio
  • 5,520
  • 4
  • 32
  • 46
0

You have few problems in your code from returning null to a double method...I have revised your program compare it against yours and if there is any part that you have questions then add a comment to my answer and I'll do my best to help you.

public static void main(String[] args) {
        run();
    }
    static  void run(){
        System.out.println("Enter coefficients for quadratic equation");
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Enter first number: ");
        Double a = keyboard.nextDouble();
        System.out.println("Enter second number: ");
        Double b = keyboard.nextDouble();
        System.out.println("Enter third number: ");
        Double c = keyboard.nextDouble();

        resultParta(a,b,c);


    }
    public static void resultParta(Double a, Double b, Double c) {
        double discriminant = Math.pow(b,2) - 4*a*c; 
        double answer1 = (-b + Math.sqrt(discriminant))/(2*a); 
        double answer2 = (-b - Math.sqrt(discriminant))/(2*a); 

        if(discriminant > 0) 
        { 
            System.out.println("answer1: " + answer1); 
            System.out.println("answer2: " + answer2); 
        } 
        else if(discriminant == 0) 
        { 
            System.out.println("answer2: " + answer1); 
        } 
        else 
        { 
            double root1complex = -b/(2*a); 
            double root1complex2 = Math.sqrt(-discriminant)/(2*a); 

            System.out.println(root1complex + " + " + root1complex2 + " i "); 
            System.out.println(" "); 
            System.out.println(root1complex + " - " + root1complex2 + " i "); 
        } 
    }
grepit
  • 21,260
  • 6
  • 105
  • 81