2016-03-06 2 views
0

У меня есть простая степенная функция, и я хочу сделать что-то вроде этого, используя два больших чисел:Clojure Значения вне диапазона для длительного

(def y 19859145917581983573N) 
(def p 27829350753993985481N) 
(defn power 
    [x n] 
    (reduce *' (repeat n x)) 
) 
(power y p) 

, и я получаю эту ошибку:

IllegalArgumentException Value out of range for long: 27829350753993985481 clojure.lang.RT.longCast (RT.java:1210) 

Есть ли способ обойти эту проблему?

+0

Что именно вы пытаетесь достичь? Вы хотите сделать модульное возведение в степень случайно? –

ответ

8

Вам нужно будет найти более эффективный метод возведения в степень, чем простое повторное умножение. Вы просите свой компьютер выполнить 27 квинтиллионных умножений! Даже если мы предположительно предположим, что вы можете выполнять миллиард таких операций в секунду, вам потребуется 900 лет, чтобы завершить этот расчет.

Но давайте предположим, что вы готовы долго ждать. Вам также придется выполнить несколько обновлений памяти на вашем компьютере: результирующее число займет примерно столько же места на вашем компьютере, как и весь объем хранилища в Интернете (по состоянию на 2016 год в любом случае: когда вы, наконец, закончите умножение , в 2900 году они, вероятно, будут иметь указатели большого пальца этого размера).

Если это не проблема для вас тоже, то вам просто придется написать версию repeat, которая использует bigints для подсчета повторений вместо длинной:

(defn repeat' [n x] 
    (lazy-seq 
    (when (> n 0N) 
     (cons x (repeat' (dec' n) x))))) 
Смежные вопросы