10

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?

Lee Phillips
  • 1,168
  • 8
  • 12
  • 1
    How many digits do you want? `sqrt(2)` can't be expressed as a rational number (as a fraction of two finite numbers). Do you want a lazy list of digits? – Dmytro Sirenko Dec 18 '12 at 18:16
  • 3
    I tried to get 100 digits by using "with-precision", but as you can see that did nothing. The answer is: I want to specify the precision. The expt function accepts bigdec arguments but only returns limited precision results. – Lee Phillips Dec 18 '12 at 18:25

2 Answers2

4

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
tnoda
  • 1,534
  • 9
  • 18
2

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"

Community
  • 1
  • 1
Arthur Ulfeldt
  • 90,827
  • 27
  • 201
  • 284