使用大量数字时,查找二次根的代码会失败

Code to find quadratic roots fail when huge numbers are used

这个问题是我在网课上遇到的,这里不得不写一个求二次根的小程序,return类型应该是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);
    }

因为我必须 return 最终根作为 Set<Integer> 类型,所以我不得不强制将 double 转换为 int returned by 'Math.sqrt'。我不确定这是否是导致问题的原因。如果是这样,我不确定如何解决这个问题,因为我无法将双精度值添加到 set<Integer>.

我用几个测试用例测试了这段代码,当使用非常大的值时它失败了,比如 c 的 ~2,000,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<BigDecimal>.

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