0

I'm trying to calculate pi using the Gregory-Leibniz method to a user-specified number of decimal places. I've never worked with the BigDecimal class before, so I don't know what I am missing here.

A simple explanation of the Leibniz method can be found here (method 3).

Esentially, It starts with the fraction 4/n where n = 1, and alternates between subtracting and adding the fraction 4/n, incrementing n to the next odd integer each iteration.

The program outputs simply 5, no matter how many decimal places are specified.

My code:

public static void calculatePi(int decimals) {
    BigDecimal pi = new BigDecimal(0.0);
    pi.setScale(decimals); // Set how many decimal points to use.
    boolean plus = true; // Add on the next iteration?
    int denominator = 1;
    BigDecimal nextVal = new BigDecimal((4/denominator));

    for(int i=0; i<decimals; i++)
    {
        if(plus == true) {
            pi = pi.add(nextVal);
        } else {
            pi = pi.subtract(nextVal);
        }
        denominator += 2;
        nextVal = new BigDecimal(4/denominator);
        plus ^= false; // Flip value of plus each iteration
    }
    System.out.println(pi.toPlainString());
}
Bassinator
  • 1,682
  • 3
  • 23
  • 50
  • I suspect I am fundamentally using `BigDecimal` wrong, but I have no idea. – Bassinator May 10 '15 at 19:09
  • 2
    This: `4/denominator` is integer arithmetic. In Java **all** integer arithmetic has an integer result. So you're not fundamentally misusing `BigDecimal`, you're fundamentally misusing Java... – Boris the Spider May 10 '15 at 19:14
  • 1
    @HCBPshenanigans there are other issues with your implementations. I have share an implementation here: http://pastebin.com/84gPGa4D. The link you shared say you need around 500000 iterations to get accurate PI with 5 decimals, but you were using the decimals parameters as number of iterations. Also use division like 4.0/denominator to turn it into double precision floating division instead of integer division. then you need to user RoundingMode when you use setScale with BigDecimals. Run the example: it will work and solve your issue. Can't share as answer now that it is marked duplicate – alainlompo May 10 '15 at 20:18
  • @HCBPshenanigans: `plus ^= false;`is not working as you expected it to work. Instead simply use `plus=!plus` – alainlompo May 10 '15 at 20:20
  • @alainlompo Could you elaborate? What IS it doing? – Bassinator May 10 '15 at 20:49
  • @HCBPshenanigans you wanted plus to flip from one boolean value to the other at each iteration (first true then false then true again, etc) so you can add then substract, .... But as I debugged your code plus keeps being true all the time, thus the fact that your result is always 5 because 4/1 + 4/3 + 4/5 + 4/7 + 4/9... = 4 + 1 + 0 + 0 + 0 ... = 5 (integer calculations). but with plus = !plus, it can turn from true to false to true again to false again... – alainlompo May 10 '15 at 20:59
  • Why then in a bugfixed version does this method work? I was able to calculate pi to 6 decimlals after 24.7 seconds. – Bassinator May 10 '15 at 21:43

0 Answers0