23

を使用して Java で立方根を取得しようとしてMath.pow(n, 1.0/3)いましたが、double を除算するため、正確な答えが返されません。たとえば、125 の場合、4.9999999999 になります。これに対する回避策はありますか? 立方根関数があることは知っていますが、より高い根を計算できるようにこれを修正したいと思います。

次のようにして、数値に整数根があるかどうかを知りたいので、丸めたくありませんMath.pow(n, 1.0 / 3) % ((int) Math.pow(n, 1.0 / 3))

4

9 に答える 9

6

Math.round関数は、double に格納できる最も近い long 値に丸めます。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
}

それが不十分な場合は、このアルゴリズムを実装してみて、結果が整数にならないようであれば早期に停止できます。

于 2015-09-13T18:33:18.170 に答える
1

が非負で正の整数であるfloor(x^(1/n))場所を計算するために、このメソッドを作成しました。少し前のことなので、なぜ機能するのか説明できませんが、これを書いたときは、正しい答えが合理的に迅速に返されることが保証されていることに満足していたと確信しています。xBigIntegern

xが正確な累乗であるかどうn-thかを確認するには、累乗された結果が再びn正確に返されるかどうかを確認できます。x

public static BigInteger floorOfNthRoot(BigInteger x, int n) {
    int sign = x.signum();
    if (n <= 0 || (sign < 0))
        throw new IllegalArgumentException();
    if (sign == 0)
        return BigInteger.ZERO;
    if (n == 1)
        return x;
    BigInteger a;
    BigInteger bigN = BigInteger.valueOf(n);
    BigInteger bigNMinusOne = BigInteger.valueOf(n - 1);
    BigInteger b = BigInteger.ZERO.setBit(1 + x.bitLength() / n);
    do {
        a = b;
        b = a.multiply(bigNMinusOne).add(x.divide(a.pow(n - 1))).divide(bigN);
    } while (b.compareTo(a) == -1);
    return a;
}

使用するには:

System.out.println(floorOfNthRoot(new BigInteger("125"), 3));

編集 上記のコメントを読んで、これが n 乗根のニュートン ラフソン法であることを思い出しました。Newton-Raphson 法には 2 次収束があります (これは日常用語で高速であることを意味します)。数十桁の数字で試してみると、ほんの一瞬で答えが得られるはずです。

メソッドを他の数値型で動作するように適応させることができますがdoubleBigDecimal私の見解では、この種のものには適していません。

于 2015-09-13T19:35:01.833 に答える
0

まあ、これはこの状況で選択する良いオプションです。あなたはこれに頼ることができます-

   System.out.println("     ");
   System.out.println("     Enter a base and then nth root");
   while(true)
   {
       a=Double.parseDouble(br.readLine());
       b=Double.parseDouble(br.readLine());
       double negodd=-(Math.pow((Math.abs(a)),(1.0/b)));
       double poseve=Math.pow(a,(1.0/b));
       double posodd=Math.pow(a,(1.0/b));
       if(a<0 && b%2==0)
       {
           String io="\u03AF";
           double negeve=Math.pow((Math.abs(a)),(1.0/b));
           System.out.println("     Root is imaginary and value= "+negeve+" "+io);
       }
       else if(a<0 && b%2==1)
       System.out.println("     Value= "+negodd);
       else if(a>0 && b%2==0)
       System.out.println("     Value= "+poseve);
       else if(a>0 && b%2==1)
       System.out.println("     Value= "+posodd);
       System.out.println("     ");
       System.out.print("     Enter '0' to come back or press any number to continue- ");
       con=Integer.parseInt(br.readLine());
       if(con==0)
       break;
       else
       {
           System.out.println("     Enter a base and then nth root");
           continue;
       }
    }
于 2016-03-28T11:22:33.110 に答える
0

これはかなり醜いハックですが、インデントを使用してそれらのいくつかに到達できます。

System.out.println(Math.sqrt(Math.sqrt(256)));
    System.out.println(Math.pow(4, 4));
    System.out.println(Math.pow(4, 9));
    System.out.println(Math.cbrt(Math.cbrt(262144)));
Result:
4.0
256.0
262144.0 
4.0

これにより、n^3 番目ごとの立方体と n^2 番目ごとのルートが得られます。

于 2017-12-04T20:22:17.967 に答える