javaquadratic

Code to find quadratic roots fail when huge numbers are used


I got this problem from an online course and here I had to write a small program to find quadratic roots, and the return type should be Set<Integer>. I am still learning Java and still not familiar working with those types.

I think everything is not wrong until this part,

if(discriminant > 0) {
        root1 = (int)(-b + Math.sqrt(discriminant)) / (2 * a);
        root2 = (int)(-b - Math.sqrt(discriminant)) / (2 * a);
        result.add(root1);
        result.add(root2);
    }

As I have to return the final roots as a Set<Integer> type I had to force convert double to int returned by 'Math.sqrt'. I am not sure if this is what causing the issues. And if so I am not sure if how to solve this, because I can't add double values to a set<Integer>.

I tested this code with few test cases, and it failed when using really big values, like ~2,000,000,000 for c.

And this is the code I came up with so far.

public class Quadratic {


public static Set<Integer> roots(int a, int b, int c) {
    int root1;
    int root2;
    int discriminant = b * b - 4 * a * c;
    Set<Integer> result = new HashSet<Integer>(); 
    
    if(discriminant < 0) {
      String rootsAreImaginary = "Roots are imaginary";
      System.out.println(rootsAreImaginary);
    }
    if(discriminant == 0) {
        root1 = (-b) / (2 * a);
        root2 = root1;
        result.add(root1);
        result.add(root2);
    }
    if(discriminant > 0) {
        root1 = (int)(-b + Math.sqrt(discriminant)) / (2 * a);
        root2 = (int)(-b - Math.sqrt(discriminant)) / (2 * a);
        result.add(root1);
        result.add(root2);
    }
    return result;
}

If there are better ways to do this, please feel free to show me. Thank you so much in advance.


Solution

  • You can use BigDecimal or BigInteger to do the computations. These would have to be stored in a Set of the proper type, e.g. Set<BigDecimal>.

    Both of those classes have methods to return the value of the related primitive (BigDecimal#doubleValue() and BigInteger#longValue()). But precision and size concerns still apply as you may not be able to fit the result into the class's related primitive.