-1

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.

Sujee0_0
  • 33
  • 6
  • @AKSingh Thank you for your comment. So then is there a way to use double as the data type to do the calculation and still output a ```Set``` value? – Sujee0_0 Jul 03 '21 at 13:26
  • 5
    In Java, the max precision for `int` is `2x10^9`. Anything beyond that will cause *overflow problems*. Even if you pass `a=b=c=10^6`, your program will fail since `a*c` results in `10^12` which an `int` cannot hold – AKSingh Jul 03 '21 at 13:27
  • 1
    We don't know the details of the exercise, but it is probably only asking for integer roots? – Henry Jul 03 '21 at 13:27
  • @Henry Thank you for the comment. I was given it like this, `public static Set roots(int a, int b, int c) { //to do }` – Sujee0_0 Jul 03 '21 at 13:29
  • 1
    @Sujee0_0 Nope there is not. If you use `int` it will result in *overflow errors* for big numbers. You can use `Long` instead of `Integer`. Your program seems logically correct. – AKSingh Jul 03 '21 at 13:30
  • 1
    You might consider using `BigDecimal` or `BigInteger` as appropriate. – WJS Jul 03 '21 at 14:30
  • @WJS thank you for the comment! Can I add BigInteger to my `Set result`? Pardon me if I sound stupid. – Sujee0_0 Jul 03 '21 at 14:40
  • 1
    Not as an Integer. It would have to be a set of that type. e.g. `Set` – WJS Jul 03 '21 at 14:43
  • @WJS okay I see, thank you! May be there are some issues with the question. But I will rewrite the code with those suggestions. – Sujee0_0 Jul 03 '21 at 14:52
  • 1
    @Sujee0_0 If you haven't done so already, check out the Wiki entry on the quadratic equation. It provides alternate formulae and references to avoid certain round off and overflow errors. – WJS Jul 03 '21 at 14:58
  • 1
    @WJS That's a great idea, thank you! it didn't come to my mind, I will check that out. – Sujee0_0 Jul 03 '21 at 15:01
  • 1
    One more observation. you have the following `root1 = (-b) / (2 * a);`. b and 2 and a are all integers. So you will drop any fractions in the division. Even if you assign to a double it is too late. E.g. 1000/33 == 30 even if you assign it to a double. Those values should all be doubles or should be cast to a double. `(double)1000/33 == 1000. /30 == 30.30303` – WJS Jul 03 '21 at 15:06
  • 1
    And be careful when comparing floating point values. `System.out.println(0. == .000000000000001);` prints false. – WJS Jul 03 '21 at 15:15
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234479/discussion-between-sujee0-0-and-wjs). – Sujee0_0 Jul 03 '21 at 16:13

1 Answers1

3

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.

WJS
  • 36,363
  • 4
  • 24
  • 39