使用幂方法计算Java中的第n个根

Sar*_*eir 17 java math double decimal root

我试图在java中使用立方根,Math.pow(n, 1.0/3)但因为它除了双精度,它不会返回确切的答案.例如,对于125,这给出了4.9999999999.有解决办法吗?我知道有一个立方根函数,但我想解决这个问题,所以我可以计算更高的根.

我不想舍入,因为我想知道一个数字是否具有整数根,通过这样做:Math.pow(n, 1.0 / 3) % ((int) Math.pow(n, 1.0 / 3)).

Tun*_*aki 7

由于无法使用任意精度计算double,因此您有三种选择:

  1. 定义一个精度,您可以使用该精度来确定double值是否为整数.
  2. 测试double您的舍入值是否是正确的结果.
  3. BigDecimal对象进行微积分,它支持任意精度的double值.

选项1

private static boolean isNthRoot(int value, int n, double precision) {
    double a = Math.pow(value, 1.0 / n);
    return Math.abs(a - Math.round(a)) < precision; // if a and round(a) are "close enough" then we're good
}
Run Code Online (Sandbox Code Playgroud)

这种方法的问题是如何定义"足够接近".这是一个主观问题,取决于您的要求.

选项2

private static boolean isNthRoot(int value, int n) {
    double a = Math.pow(value, 1.0 / n);
    return Math.pow(Math.round(a), n) == value;
}
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是不需要定义精度.但是,我们需要执行另一个pow操作,因此这会影响性能.

选项3

没有内置方法来计算BigDecimal的双倍幂.这个问题将为您提供有关如何做到这一点的见解.


Man*_*dis 5

Math.round功能将全面到可以存储到双最接近的长期价值.您可以比较2个结果以查看该数字是否具有整数立方根.

double dres = Math.pow(125, 1.0 / 3.0);
double ires = Math.round(dres);
double diff = Math.abs(dres - ires);
if (diff < Math.ulp(10.0)) {
    // has cubic root
}
Run Code Online (Sandbox Code Playgroud)

如果这不够,你可以尝试实现这个算法,如果结果似乎不是整数,则提前停止.