Вычисление степеней целых чисел



Существует ли в Java какой-либо другой способ вычисления степени целого числа?



Я использую Math.pow(a, b) сейчас, но он возвращает двойник, и это обычно много работы, и выглядит менее чистым, когда вы просто хотите использовать целые числа (степень тогда также всегда будет приводить к целому числу).



Есть ли что-то такое же простое, как a**b, как в Python?

685   13  

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 методы и аргументы pass int.

Ну, вы можете просто использовать 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

    Ничего не найдено.