Javaに整数のべき乗を計算する他の方法はありますか?
現在Math.pow(a, b)
を使用していますが、double
を返します。これは通常多くの作業であり、int
sを使用したい場合はあまりきれいに見えません(電源も常に結果はint
)になります。
Pythonのようなa**b
のような単純なものはありますか?
整数は32ビットのみです。これは、その最大値が2^31 -1
であることを意味します。ご覧のとおり、非常に小さな数値の場合、整数で表すことのできない結果がすぐに得られます。 Math.pow
がdouble
を使用する理由です。
任意の整数精度が必要な場合は、 BigInteger.pow
を使用します。しかし、それはもちろんあまり効率的ではありません。
最高のアルゴリズムは、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)です。参照: 詳細
いいえ、a**b
ほど短いものはありません
ダブルスを回避したい場合の簡単なループを次に示します。
long result = 1;
for (int i = 1; i <= b; i++) {
result *= a;
}
pow
を使用して結果を整数に変換する場合は、次のように結果をキャストします。
int result = (int)Math.pow(a, b);
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)
Google Guavaには整数用の数学ユーティリティがあります。 IntMath
以前に使用したようにMath.pow(a,b)
を使用し、その前に(int)
を使用してその値を変換するだけです。以下はその例として使用できます。
int x = (int) Math.pow(a,b);
a
およびb
は、必要に応じてdouble
またはint
の値にすることができます。これにより、必要に応じて出力が整数値に変換されます。
グアバの数学ライブラリには、正確な整数のべき乗を計算するときに役立つ2つのメソッドがあります。
pow(int b, int k)
bのk乗を計算し、オーバーフローでラップします
checkedPow(int b, int k)
は、オーバーフロー時にArithmeticException
をスローすることを除いて同一です
個人的にcheckedPow()
は整数の累乗の私のニーズのほとんどを満たし、ダブルバージョンや丸めなどを使用するよりもクリーンでサターです。不可能が可能になった場合)。
long
の結果を取得する場合は、対応する LongMath
メソッドを使用して、int
引数を渡すだけです。
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;
}
}
パワーを計算するための繰り返し二乗アルゴリズムの単純な(オーバーフローまたは引数の有効性のチェックなし)実装:
/** 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を表すのに必要なビット数に線形です)。
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;
}
}
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)));
}
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 );
}
}
以下のロジックを使用して、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;
}
}