Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arbitrary precision exponentiation in Clojure

Tags:

math

clojure

Is there way to perform arbitrary precision exponentiation in Clojure? I've tried Math/pow and the expt function from clojure.math.numeric-tower, but both will only return limited precision. For example:

(with-precision 100 (expt 2 1/2))
=> 1.4142135623730951

How do I get more digits?

like image 833
Lee Phillips Avatar asked Dec 18 '12 18:12

Lee Phillips


2 Answers

Apfloat for Java provides fast arbitrary precision arithmetic. You can easily use it by adding the following dependency information to your project.clj file, if your project comes with Leiningen.

[org.apfloat/apfloat "1.6.3"]

You can perform arbitrary precision exponentiation in Clojure using Apfloat. For example:

user> (import '(org.apfloat Apfloat ApfloatMath))
org.apfloat.ApfloatMath

user> (-> (Apfloat. 2M 100) (ApfloatMath/pow (Apfloat. 0.5M 100)))
1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727
like image 138
tnoda Avatar answered Nov 15 '22 23:11

tnoda


math/expt is likely not the function you are looking for as it returns a double instead of a BigDecimal in this context, and hence ignores your with-precision statement:

Returns an exact number if the base is an exact number and the power is an integer, otherwise returns a double.

user> (type (with-precision 100 (math/expt 2M 1/2)))
java.lang.Double

the answer to this question seems to cover how to get arbitrary precision out of BigDecimal exponentiation. BigDecimal seems not to provide this "out of the box"

like image 44
Arthur Ulfeldt Avatar answered Nov 15 '22 23:11

Arthur Ulfeldt