web-dev-qa-db-ja.com

整数のべき乗の計算

Javaに整数のべき乗を計算する他の方法はありますか?

現在Math.pow(a, b)を使用していますが、doubleを返します。これは通常多くの作業であり、intsを使用したい場合はあまりきれいに見えません(電源も常に結果はint)になります。

Pythonのようなa**bのような単純なものはありますか?

54
Hidde

整数は32ビットのみです。これは、その最大値が2^31 -1であることを意味します。ご覧のとおり、非常に小さな数値の場合、整数で表すことのできない結果がすぐに得られます。 Math.powdoubleを使用する理由です。

任意の整数精度が必要な場合は、 BigInteger.pow を使用します。しかし、それはもちろんあまり効率的ではありません。

30
JB Nizet

最高のアルゴリズムは、a ^ bの再帰的パワー定義に基づいています。

long pow (long a, int b)
{
    if ( b == 0)        return 1;
    if ( b == 1)        return a;
    if (isEven( b ))    return     pow ( a * a, b/2); //even a=(a^2)^b/2
    else                return a * pow ( a * a, b/2); //odd  a=a*(a^2)^b/2

}

操作の実行時間はO(logb)です。参照: 詳細

34
Baykoch

いいえ、a**bほど短いものはありません

ダブルスを回避したい場合の簡単なループを次に示します。

long result = 1;
for (int i = 1; i <= b; i++) {
   result *= a;
}

powを使用して結果を整数に変換する場合は、次のように結果をキャストします。

int result = (int)Math.pow(a, b);
27
Petar Minchev

2の累乗の場合は、シンプルで高速なシフト式1 << exponentを使用できることに留意してください

例:

22 = 1 << 2 = (int) Math.pow(2, 2)
210 = 1 << 10 = (int) Math.pow(2, 10)

より大きい指数(31を超える)の場合は、代わりにlongを使用します

232 = 1L << 32 = (long) Math.pow(2, 32)

ところで。 Kotlinでは、<<の代わりにshlがあります。

(Java)1L << 32 = 1L shl 32(kotlin)

12

Google Guavaには整数用の数学ユーティリティがあります。 IntMath

6
ant

以前に使用したようにMath.pow(a,b)を使用し、その前に(int)を使用してその値を変換するだけです。以下はその例として使用できます。

int x = (int) Math.pow(a,b);

aおよびbは、必要に応じてdoubleまたはintの値にすることができます。これにより、必要に応じて出力が整数値に変換されます。

3

グアバの数学ライブラリには、正確な整数のべき乗を計算するときに役立つ2つのメソッドがあります。

pow(int b, int k) bのk乗を計算し、オーバーフローでラップします

checkedPow(int b, int k) は、オーバーフロー時にArithmeticExceptionをスローすることを除いて同一です

個人的にcheckedPow()は整数の累乗の私のニーズのほとんどを満たし、ダブルバージョンや丸めなどを使用するよりもクリーンでサターです。不可能が可能になった場合)。

longの結果を取得する場合は、対応する LongMath メソッドを使用して、int引数を渡すだけです。

2
BeeOnRope

Qx__回答(境界、チェック、負のnumsチェック)を変更できました。自己責任。 0 ^ -1、0 ^ -2など。0を返します。

private static int pow(int x, int n) {
        if (n == 0)
            return 1;
        if (n == 1)
            return x;
        if (n < 0) { // always 1^xx = 1 && 2^-1 (=0.5 --> ~ 1 )
            if (x == 1 || (x == 2 && n == -1))
                return 1;
            else
                return 0;
        }
        if ((n & 1) == 0) { //is even 
            long num = pow(x * x, n / 2);
            if (num > Integer.MAX_VALUE) //check bounds
                return Integer.MAX_VALUE; 
            return (int) num;
        } else {
            long num = x * pow(x * x, n / 2);
            if (num > Integer.MAX_VALUE) //check bounds
                return Integer.MAX_VALUE;
            return (int) num;
        }
    }
1
Smarty77

パワーを計算するための繰り返し二乗アルゴリズムの単純な(オーバーフローまたは引数の有効性のチェックなし)実装:

/** Compute a**p, assume result fits in a 32-bit signed integer */ 
int pow(int a, int p)
{
    int res = 1;
    int i1 = 31 - Integer.numberOfLeadingZeros(p); // highest bit index
    for (int i = i1; i >= 0; --i) {
        res *= res;
        if ((p & (1<<i)) > 0)
            res *= a;
    }
    return res;
}

時間の複雑さは指数pの対数です(つまり、pを表すのに必要なビット数に線形です)。

1
import Java.util.*;

public class Power {

    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        int num = 0;
        int pow = 0;
        int power = 0;

        System.out.print("Enter number: ");
        num = sc.nextInt();

        System.out.print("Enter power: ");
        pow = sc.nextInt();

        System.out.print(power(num,pow));
    }

    public static int power(int a, int b)
    {
        int power = 1;

        for(int c = 0; c < b; c++)
            power *= a;

        return power;
    }

}
1
mark lamban

baseはパワーアップする数値、nはパワー、nが0の場合は1を返し、nが1の場合はベースを返します。条件が満たされない場合は、式base *(powerN(base、n-1))例:この式を使用して2を上げると、2(base)* 2(powerN(base、n-1))になります。

public int power(int base, int n){
   return n == 0 ? 1 : (n == 1 ? base : base*(power(base,n-1)));
}
0
Milze

Python(a ** bで累乗を計算できる)とは異なり、Javaには、2つの累乗の結果を得るためのそのようなショートカット方法がありません。 Javaには、Mathクラスにpowという名前の関数があり、Double値を返します。

double pow(double base, double exponent)

ただし、同じ関数を使用して整数のべき乗を計算することもできます。次のプログラムで同じことを行い、最終的に結果を整数に変換しています(型キャスト)。例に従ってください:

import Java.util.*;
import Java.lang.*; // CONTAINS THE Math library
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n= sc.nextInt(); // Accept integer n
        int m = sc.nextInt(); // Accept integer m
        int ans = (int) Math.pow(n,m); // Calculates n ^ m
        System.out.println(ans); // prints answers
    }
}

または、Java.math.BigInteger.pow(int exponent)は、値が(this ^ exponent)であるBigIntegerを返します。指数は、BigIntegerではなく整数です。例:

import Java.math.*;
public class BigIntegerDemo {
public static void main(String[] args) {
      BigInteger bi1, bi2; // create 2 BigInteger objects          
      int exponent = 2; // create and assign value to exponent
      // assign value to bi1
      bi1 = new BigInteger("6");
      // perform pow operation on bi1 using exponent
      bi2 = bi1.pow(exponent);
      String str = "Result is " + bi1 + "^" +exponent+ " = " +bi2;
      // print bi2 value
      System.out.println( str );
   }
}
0
Pritam Mullick

以下のロジックを使用して、aのn乗を計算します。

通常、aのn乗を計算する場合。 「a」にn回を掛けます。このアプローチの時間の複雑さはO(n)になります。nを2で割り、Exponentattion = n/2になるまで「a」を掛けます。値を2倍にします。これで、時間計算量はO(n/2)に削減されました。

public  int calculatePower1(int a, int b) {
    if (b == 0) {
        return 1;
    }

    int val = (b % 2 == 0) ? (b / 2) : (b - 1) / 2;

    int temp = 1;
    for (int i = 1; i <= val; i++) {
        temp *= a;
    }

    if (b % 2 == 0) {
        return temp * temp;
    } else {
        return a * temp * temp;
    }
}
0
Yuvaraj Ram