2015-11-10 5 views

ответ

9

Нет, нет ничего эквивалентного для pow, встроенного в Java. (Только pow методы, встроенные в Java являются Math.pow, который принимает двойников и не переполнения таким же образом целые делать, и BigInteger.pow, которые не переполнения, потому что BigInteger s может быть сколь угодно большим.)

Если сторонние библиотеки приемлемы, хотя у Гуавы есть, например, IntMath.checkedPow, который делает то, что вы ищете.

+0

Я думаю, вы также должны упомянуть 'LongMath.checkedPow'. Я думаю (хотя я мог ошибаться), это тривиально для 'int', потому что каждый' int' может быть представлен как double, поэтому вам просто нужно сделать 'Math.pow (a, b)' и сравнить с 'Integer.MAX_VALUE '. –

+0

@Louis Если я использую 'BigInteger', я не могу беспокоиться о размере полученного числа? – Claudia

+1

@Claudia [BigInteger] (https://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html): «целые числа произвольной точности ... Все детали в Спецификации, касающиеся переполнение игнорируется, так как BigIntegers сделаны настолько большими, насколько это необходимо для учета результатов операции ». –

0

Целые числа всего 32 бита. поэтому максимальное значение равно 2^31 -1. (При использовании BigInteger.pow.Это менее эффективно.) Таким образом, вы можете проверить вручную и выбросить Исключение при необходимости else использовать Math.pow, который использует двойной.

+3

Это не ответ. Вопрос в том, есть ли такой метод (я предполагаю, что в Java 8 API). – Turing85

+0

То, что я пытаюсь сказать, это то, что мы можем написать собственный код, и, конечно же, исключение сборки не существует. Благодарю. – Chirag

+0

Java завершает работу, поэтому предполагается, что вы можете написать любой алгоритм в Java. – Turing85

4

Как указано Chirag, целые числа бросают исключения, когда они переполняются, а двойники - нет. Не для того, чтобы стать слишком конкретным, но, в основном, удвоения в памяти хранятся очень похожими на научную нотацию, поскольку они представляют собой целое число * 2^(некоторая мощность) и, следовательно, никогда не переполняются, а умножаются на такие большие или малые 2^некоторая власть), что они полностью теряют свою точность. Поэтому вы можете думать о двойном переполнении, когда они полностью теряют свою точность и печатаются либо как Infinity, либо -Infinity.

Итак, вам нужно будет вручную проверить, произошло ли переполнение, проверив, имеет ли результирующее значение Double.POSITIVE_INFINITY или Double.NEGATIVE_INFINITY.

Вот некоторые примеры кода, чтобы показать, что я имею в виду:

public static void main(String[] args) throws Exception 
{ 
    double a = Double.MAX_VALUE; // highest possible double 
    double b = Double.MAX_VALUE; // highest possible double 

    if (Math.pow(a, b) == Double.POSITIVE_INFINITY || Math.pow(a, b) == Double.NEGATIVE_INFINITY) 
    { 
     throw new ArithmeticException("Double Overflow"); 
    } 
} 
1

Если это нормально, чтобы иметь свою собственную реализацию, вы могли бы сделать что-то вроде этого:

private static final int[] maxBaseForExponent = IntStream.range(0, 30) 
     .map(e -> (int) Math.pow(Integer.MAX_VALUE, 1d/e)).toArray(); 

public static int powExact(int base, int exponent) { 
    if (exponent < 0) { 
     throw new ArithmeticException("Negative exponent"); 
    } 
    if ((base < -1 || base > 1) && (exponent > 30 || base > maxBaseForExponent[exponent]) 
      && !(base == -2 && exponent == 31)) { 
     throw new ArithmeticException("Overflow"); 
    } 
    switch (base) { 
    case -2: 
     return (exponent & 1) == 0 ? 1 << exponent : -1 << exponent; 
    case -1: 
     return (exponent & 1) == 0 ? 1 : -1; 
    case 0: 
     return exponent == 0 ? 1 : 0; 
    case 1: 
     return 1; 
    case 2: 
     return 1 << exponent; 
    default: 
    } 
    int result = 1; 
    while (exponent != 0) { 
     if ((exponent & 1) != 0) { 
      result *= base; 
     } 
     exponent >>= 1; 
     base *= base; 
    } 
    return result; 
} 

Взял алгоритм из here , и изменил его, чтобы проверить переполнение, используя массив, который содержит максимальное основание для каждого показателя от 0 до 30.

Смежные вопросы