Вычисление степеней целых чисел
Существует ли в Java какой-либо другой способ вычисления степени целого числа?
Я использую Math.pow(a, b) сейчас, но он возвращает двойник, и это обычно много работы, и выглядит менее чистым, когда вы просто хотите использовать целые числа (степень тогда также всегда будет приводить к целому числу).
Есть ли что-то такое же простое, как a**b, как в Python?
13 ответов:
Целые числа имеют только 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);
В Google Guava есть математические утилиты для целых чисел. IntMath
Математические библиотеки гуавы предлагают два метода, которые полезны при вычислении точных целых степеней:
pow(int b, int k)вычисляет b до K-й степени, и обертывает на переполнение
checkedPow(int b, int k)идентичен за исключением того, что он бросаетArithmeticExceptionна переполнениеЛично
checkedPow()удовлетворяет большинству моих потребностей в целочисленном возведении в степень и является более чистым и безопасным, чем использование двойных версий и округления и т. д. Почти во всех местах, где мне нужна функция питания, переполнение является ошибкой (или невозможно, но я хочу, чтобы мне сказали, если невозможное когда-нибудь станет возможным).Если вы хотите получить результат
long, Вы можете просто использовать соответствующийLongMathметоды и аргументы passint.
Ну, вы можете просто использовать
Math.pow(a,b), Как вы использовали ранее, и просто преобразовать его значение, используя(int)перед ним. Ниже может быть использован в качестве примера к нему.int x = (int) Math.pow(a,b);Где
aиbмогут бытьdoubleилиintзначениями, как вы хотите. Это просто преобразует его выходные данные в целочисленное значение, как вам требуется.
Когда это сила 2. Имейте в виду, что вы можете использовать простой и быстрый показатель 1
22 =
(int) Math.pow(2, 2) == 1 << 2
210 =(int) Math.pow(2, 10) == 1 << 10Для больших показателей (более 31) используйте long вместо
232 =
(long) Math.pow(2, 32) == 1L << 32Кстати. в Котлине у вас есть
shlвместо<<так что(java)
1L << 32 == 1L shl 32(kotlin)
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; } }
Мне удалось изменить (границы, даже проверить, отрицательные числа проверить) QX _ _ ответ. Используйте на свой страх и риск. 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; }Сложность времени является логарифмической, чтобы показатель п (т. е. линейное количество бит, требующихся для представления п).
В отличие от Python (где степени могут быть вычислены с помощью a**b) , JAVA не имеет такого быстрого способа достижения результата степени двух чисел. Java имеет функцию pow в математическом классе, которая возвращает двойное значение
double pow(double base, double exponent)Но вы также можете вычислить степени целого числа, используя ту же функцию. В следующей программе я сделал то же самое и, наконец, я преобразую результат в целое число (typecasting). Следуйте примеру:
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)возвращает a 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 ); } }
Используйте нижеприведенную логику для вычисления N-й степени a.
Обычно, если мы хотим вычислить N степеней a. мы умножим 'a' на n раз.Временная сложность такого подхода составит O(n) Разделите степень n на 2, вычислите экспоненту = умножьте "a" только до n/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; } }
Base-это число, которое вы хотите включить, n-это мощность, мы возвращаем 1, Если n равно 0, и мы возвращаем базу, если 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))); }
Comments