44

Java's BigDecimal.pow(int) method only accepts an integer parameter, no BigDecimal parameter.

Is there a library, like Apache's commons-lang, that supports BigDecimal.pow(BigDecimal)? It should be able to do calculate "1.21".pow("0.5") to return "1.1".

Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120
  • 1
    Looked at the source? http://javasourcecode.org/html/open-source/jdk/jdk-6u23/java.math/BigDecimal.java.html probably not too difficult to implement your own. – arynaq May 13 '13 at 08:14
  • 1
    Maybe this source code (http://stackoverflow.com/a/3590314/592228) can be of help? You wouldn't need any other library. – tstorms May 13 '13 at 08:17
  • 1
    I have already given the solution there http://stackoverflow.com/questions/11848887/bigdecimal-to-the-power-of-bigdecimal-on-java-android/22556217#22556217 – softawareblog.com Mar 21 '14 at 10:37
  • 2
    For those as me who searched for it : https://github.com/eobermuhlner/big-math – Benj Aug 27 '18 at 08:43
  • I didn't want to use a third party library so these solutions didn't work for me. I just converted the BigDecimal to double, did pow with double, and converted it back after.: return value.toDouble().pow(other.toDouble()).toBigDecimal() – mliu Sep 11 '20 at 04:15

3 Answers3

40

There is a Math.BigDecimal implementation of core mathematical functions with source code available from the Cornell University Library here (also you can download the library as a tar.gz). Here is a sample of the library use:

import org.nevec.rjm.*;
import java.math.BigDecimal;

public class test {
    public static void main(String... args) {
        BigDecimal a = new BigDecimal("1.21");
        BigDecimal b = new BigDecimal("0.5");

        System.out.println(BigDecimalMath.pow(a, b).toString());
    }
}

Prints out:

1.1

Update

The license information is now clear in the May 2015 update:

The full source code is made available under the LGPL v3.0.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
higuaro
  • 15,730
  • 4
  • 36
  • 43
  • Interesting. What's the license of this code? Is it open source? BSD, MIT or ASL licensed? – Geoffrey De Smet May 17 '13 at 08:22
  • 1
    How can I add this library as an external jar file? I don't see any jar file. – the_prole Jul 15 '14 at 15:52
  • 2
    @the_prole Download the [tar.gz](http://arxiv.org/src/0908.3030v2) file, extract the content and then locate the `anc` folder, `cd` into it, then execute `make BigDecimalMath.jar`, this should build the `BigDecimalMath.jar` file that you can use as an external library – higuaro Jul 15 '14 at 19:33
  • @higuaro Thanks, i made a new package in eclipse, closed eclipse, copied and pasted the .java files into the package, and re-opened eclipse. Worked fine for me. I don't know how to execute a make file. – the_prole Jul 16 '14 at 00:50
  • 3
    @higuaro Any idea why I get this result? BigDecimalMath.pow(3,3)=1E+1 – the_prole Jul 16 '14 at 10:47
  • 1
    I have the same problem as @the_prole it's rounding way too much... – Steffen Feb 10 '15 at 15:28
  • You can use check if the power is an integer using something like `x == Math.ceil(x)` and then using the standard `BigDecimal.pow(int)` which should be more precise for the particular case – higuaro Oct 25 '15 at 11:05
  • I would recommend not using this. Using JUnitQuickcheck for verifying that `x^1` is the identity function yielded `4^1=3`, with this library. – derabbink May 16 '17 at 09:01
  • This function does not support negative bases – lost_in_the_source Jul 03 '18 at 18:03
  • @the_prole (and others) The `BigDecimal`s you pass in need to have a sufficiently high precision: pow(3.00, 3.00) returns 27. But it seems if you put in `BigDecimal`s of precision p you get back a result of precision p-1 (pow(3.000, 3.000) returns 27.0; pow(3.0, 3.0) returns 30 (3E+1)). – René Feb 19 '20 at 14:15
  • @higuaro how do I extract my tar.gz file using Windows? I can't extract it, even with WinZip. – Laser Infinite Mar 31 '20 at 15:42
  • 1
    Hey @NoobyProgrammer. For Windows, perhaps you could try the 7zip UI, here's a link: https://www.7-zip.org/download.html It supports a wide range of compression related formats. – higuaro Apr 01 '20 at 03:45
  • @higuaro what is the 'cd' folder mean? – Laser Infinite Apr 01 '20 at 15:03
  • 1
    @NoobyProgrammer probably in your context `cd` means `current directory`. On the command line, `cd` refers to the program that changes the current directory, more info here: https://www.digitalcitizen.life/command-prompt-how-use-basic-commands – higuaro Apr 02 '20 at 00:23
  • 1
    @higuaro thanks I've already implemented it into my programs – Laser Infinite Apr 02 '20 at 12:26
  • I tried this library but ended up using https://github.com/eobermuhlner/big-math instead which I can really recommend. The library suggested in this answer was much slower and threw exceptions more often. Also, in the library suggested in this comment, all functions take a `MathContext` as well, analoguously to the functions in `BigDecimal` which the library suggested in this answer does not. – fast-reflexes Nov 01 '20 at 10:44
7

Havent used, but saw suanshu. An open source version in github (https://github.com/nmdev2020/SuanShu).

BigDecimalUtils has a pow() which suits your needs

public static java.math.BigDecimal pow(java.math.BigDecimal a,
                                       java.math.BigDecimal b)
Compute a to the power of b.
H Li
  • 15
  • 2
rajesh
  • 3,247
  • 5
  • 31
  • 56
  • SuanShu is a good answer, unfortunately it has a commercial license (not compatible with my apache licensed work) and it is not available on maven central (not compatible with distribution method). – Geoffrey De Smet May 08 '13 at 13:46
  • 1
    Looks like it has since been made open source under Apache 2.0 license. See https://github.com/aaiyer/SuanShu – Ben Holland Dec 17 '19 at 16:33
5

The Apfloat library seems to be doing this, check the API docs.

ApcomplexMath.pow(Apcomplex z, Apcomplex w)

Apcomplex is a wrapper class for e.g. a BigDecimal.

tstorms
  • 4,941
  • 1
  • 25
  • 47
  • LGPL and in Maven: nice. Only have to figure out to convert `BigDecimal` to and from `Apcomplex` – Geoffrey De Smet May 14 '13 at 08:44
  • 1
    According to the javadoc `new Apcomplex(new Apfloat(BigDecimal))` should do the trick. – tstorms May 14 '13 at 08:47
  • 1
    new BigDecimal(String.format("%s", ApfloatMath.pow(new Apfloat(v, 10), new Apfloat(p, 10)))); – Altair7852 Jan 12 '15 at 02:35
  • 1
    not works correct `new BigDecimal(String.format("%s", ApfloatMath.pow(new Apfloat(new BigDecimal("2.0"), 16), new Apfloat(new BigDecimal("3.0"), 16))));` return `8.000000000000001` not 8 – Anton Oct 27 '16 at 12:38
  • 1
    @tstorms Why use ApcomplexMath for real exponentiation? Check out ApfloatMath https://github.com/mtommila/apfloat/blob/0c583db22751d56eef9ec0bf40f724f2f4374603/apfloat/src/main/java/org/apfloat/ApfloatMath.java#L1483 – Rag Sep 28 '17 at 07:15