2015-12-24 5 views
2

Так что я использую этот модульный алгоритм экспоненциальности, который я видел в Википедии где-то, и он отлично работает для меня для небольших чисел. Но когда я использую большие числа (например, 7000000000) всегда возвращает 0.long mod opertaion возвращает int Java

public static void main(String[] args) { 
    System.out.println(modPow(2L, 7000000000L - 1L, 7000000000L)); 
} 

public static long modPow(long base, long exponent, long modulus) { 
    long result = 1L; 
    base = base % modulus; 
    while(exponent > 0) { 
     if(exponent % 2 == 1) { 
      result = (result * base) % modulus; 
     } 
     exponent = exponent >> 1; 
     System.out.println(result); 
     base = (base*base) % modulus; 
    } 
    return result; 
} 

Я отслеживал проблему вниз к переменному результату, так как функция петле имеет значение:

2 
8 
128 
32768 
2147483648 
-4854775808 
0 
0 
...0s onward 

Это ясно показывает, что переменная результата хранится как int, но я четко определил ее как длинную. Я попытался добавить (длинный) ко всем вычислениям в случае, если он по какой-то причине отличает его по int, но это не работает.

Возможно, что-то простое или базовое, что мне не хватает, но я не понимаю, почему это не работает. Любая помощь приветствуется.

ответ

2

result * base переполнение long.

Добавить что-то вроде ниже заявление внутри if

System.out.println("result * base = " + result*base);` 

, и вы увидите:

result * base = 2 
2 
result * base = 8 
8 
result * base = 128 
128 
result * base = 32768 
32768 
result * base = 2147483648 
2147483648 
result * base = -9223372036854775808 
-4854775808 

Long.MAX_VALUE Обратите внимание, что это 9223372036854775807

+0

Ах хорошо, это имеет смысл сейчас. Я предполагаю, что нелегко, почему обойти это без необходимости использовать другой алгоритм или начать использовать большие целые числа? –

+0

Я думаю, что «BigInteger» - это путь. –