Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use biginteger in Clojure?

I am trying to calculate the 500th Fibonacci number in Clojure:

(defn fib-pair [[a b]] [b (+ a b)])
(nth (map first (iterate fib-pair [1 1])) 500)
ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)

This program failed because the number is too big: integer overflow. How to solve this problem?

like image 957
Nick Avatar asked Dec 11 '22 05:12

Nick


2 Answers

The default integer type in Clojure is long. If you want to specify that an integer literal should be considered a clojure.lang.BigInt just add an N right after the number.

(defn fib-pair [[a b]] [b (+ a b)])
(nth (map first (iterate fib-pair [1N 1N])) 500)
;= 225591516161936330872512695036072072046011324913758190588638866418474627738686883405015987052796968498626N

You can actually get away with just specifying only one of the two initial values as a BigInt since:

(+ 1N 1)
;= 2N
(type (+ 1N 1))
;= clojure.lang.BigInt
like image 123
juan.facorro Avatar answered Dec 25 '22 22:12

juan.facorro


You can use clojure.core/+' instead of clojure.core/+ in fib-pair

This will auto promote longs when needed.

(defn fib-pair [[a b]] [b (+' a b)])
like image 38
Kyle Avatar answered Dec 25 '22 22:12

Kyle