使用大数时查找二次根的代码失败

问题描述

我从在线课程中得到了这个问题,在这里我不得不编写一个小程序来找到二次根,返回类型应该是 Set<Integer>。我仍在学习 Java,仍然不熟悉使用这些类型。

我认为这部分之前一切都没有错,

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);
    }

由于我必须将最终根作为 Set<Integer> 类型返回,因此我不得不强制将 double 转换为由“Math.sqrt”返回的 int。我不确定这是否是导致问题的原因。如果是这样,我不确定如何解决这个问题,因为我无法向 set<Integer> 添加双精度值。

我用很少的测试用例测试了这段代码,但在使用非常大的值时失败了,比如 c 的 ~2,000,000。

这是我目前想出的代码

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;
}

如果有更好的方法可以做到这一点,请随时告诉我。在此先感谢您。

解决方法

您可以使用 BigDecimalBigInteger 进行计算。这些必须存储在适当类型的 Set 中,例如Set<BigDecimal>

这两个类都有返回相关原语 (BigDecimal#doubleValue() and BigInteger#longValue()) 值的方法。但是精度和大小问题仍然适用,因为您可能无法将结果放入类的相关原语中。