13.1 Estimates of p and Ramanujan's Formulas Some people claim that the Christian Bible implies that the value of p is 3. Other estimates that were used throughout history include (Babylonians, ca. 2000 B.C. ), (Egyptians, ca. 2000 B.C. ), (Archimedes, 3rd century B.C ), (Ptolemy, 2nd century A.D. ), (Liu Hui, A.D. 263), (Valentinus Otho, A.D. 1573), and (Simon Duchesne, A.D. 1583). In 1914, Ramanujan [2] published several remarkable formulas that give approximate values for p that are accurate to 15 to 31 decimal places. These formulas are shown in Table 13-1.
Table 13-1. Ramanujan's formulas for p .
Program 13-1 tests these formulas, using the BigFunctions class we developed in Chapter 12. See Listing 13-1. Listing 13-1 Estimates of p computed by Ramanujan's formulas.package numbercruncher.program13_1; import java.math.BigDecimal; import numbercruncher.mathutils.BigFunctions; /** * PROGRAM 13-3: Ramanujan's Formulas for pi * * Compute estimates of pi using Ramanujan's formulas. */ public class PiRamanujan { private void compute() { int digits; // number of digits int scale; BigDecimal term, a, b, c, d, e, lnArg, pi; BigDecimal sqrt2, sqrt5, sqrt6, sqrt10, sqrt13, sqrt29; BigDecimal sqrt130, sqrt142, sqrt190, sqrt310, sqrt522; // --- 15 digits --- digits = 15; scale = digits + 2; sqrt2 = BigFunctions.sqrt(BigDecimal.valueOf( 2), scale); sqrt5 = BigFunctions.sqrt(BigDecimal.valueOf( 5), scale); sqrt13 = BigFunctions.sqrt(BigDecimal.valueOf( 13), scale); sqrt130 = BigFunctions.sqrt(BigDecimal.valueOf(130), scale); term = BigDecimal.valueOf(12) .divide(sqrt130, scale, BigDecimal.ROUND_HALF_EVEN); a = BigDecimal.valueOf(2).add(sqrt5); b = BigDecimal.valueOf(3).add(sqrt13); lnArg = a.multiply(b) .divide(sqrt2, BigDecimal.ROUND_HALF_EVEN) .setScale(scale, BigDecimal.ROUND_HALF_EVEN); pi = term.multiply(BigFunctions.ln(lnArg, scale)) .setScale(digits, BigDecimal.ROUND_HALF_EVEN); System.out.println(digits + " digits: " + pi); // --- 16 digits --- digits = 16; scale = digits + 2; sqrt2 = BigFunctions.sqrt(BigDecimal.valueOf( 2), scale); sqrt142 = BigFunctions.sqrt(BigDecimal.valueOf(142), scale); term = BigDecimal.valueOf(24) .divide(sqrt142, scale, BigDecimal.ROUND_HALF_EVEN); a = BigDecimal.valueOf(10) .add(BigDecimal.valueOf(11).multiply(sqrt2)) .divide(BigDecimal.valueOf(4), scale, BigDecimal.ROUND_HALF_EVEN); b = BigDecimal.valueOf(10) .add(BigDecimal.valueOf(7).multiply(sqrt2)) .divide(BigDecimal.valueOf(4), scale, BigDecimal.ROUND_HALF_EVEN); lnArg = BigFunctions.sqrt(a, scale) .add(BigFunctions.sqrt(b, scale)); pi = term.multiply(BigFunctions.ln(lnArg, scale)) .setScale(digits, BigDecimal.ROUND_HALF_EVEN); System.out.println(digits + " digits: " + pi); // --- 18 digits --- digits = 18; scale = digits + 2; sqrt2 = BigFunctions.sqrt(BigDecimal.valueOf( 2), scale); sqrt10 = BigFunctions.sqrt(BigDecimal.valueOf( 10), scale); sqrt190 = BigFunctions.sqrt(BigDecimal.valueOf(190), scale); term = BigDecimal.valueOf(12) .divide(sqrt190, scale, BigDecimal.ROUND_HALF_EVEN); a = BigDecimal.valueOf(2).multiply(sqrt2).add(sqrt10); b = BigDecimal.valueOf(3).add(sqrt10); lnArg = a.multiply(b) .setScale(scale, BigDecimal.ROUND_HALF_EVEN); pi = term.multiply(BigFunctions.ln(lnArg, scale)) .setScale(digits, BigDecimal.ROUND_HALF_EVEN); System.out.println(digits + " digits: " + pi); // --- 22 digits --- digits = 22; scale = digits + 2; sqrt2 = BigFunctions.sqrt(BigDecimal.valueOf( 2), scale); sqrt5 = BigFunctions.sqrt(BigDecimal.valueOf( 5), scale); sqrt10 = BigFunctions.sqrt(BigDecimal.valueOf( 10), scale); sqrt310 = BigFunctions.sqrt(BigDecimal.valueOf(310), scale); term = BigDecimal.valueOf(12) .divide(sqrt310, scale, BigDecimal.ROUND_HALF_EVEN); a = BigDecimal.valueOf(3).add(sqrt5); b = BigDecimal.valueOf(2).add(sqrt2); c = BigDecimal.valueOf(5) .add(BigDecimal.valueOf(2).multiply(sqrt10)); d = BigFunctions.sqrt(BigDecimal.valueOf(61) .add(BigDecimal.valueOf(20) .multiply(sqrt10)), scale); e = c.add(d).multiply(a).multiply(b) .setScale(scale, BigDecimal.ROUND_HALF_EVEN); lnArg = e.divide(BigDecimal.valueOf(4), scale, BigDecimal.ROUND_HALF_EVEN); pi = term.multiply(BigFunctions.ln(lnArg, scale)) .setScale(digits, BigDecimal.ROUND_HALF_EVEN); System.out.println(digits + " digits: " + pi); // --- 31 digits --- digits = 31; scale = digits + 2; sqrt2 = BigFunctions.sqrt(BigDecimal.valueOf( 2), scale); sqrt6 = BigFunctions.sqrt(BigDecimal.valueOf( 6), scale); sqrt29 = BigFunctions.sqrt(BigDecimal.valueOf( 29), scale); sqrt522 = BigFunctions.sqrt(BigDecimal.valueOf(522), scale); term = BigDecimal.valueOf(4) .divide(sqrt522, scale, BigDecimal.ROUND_HALF_EVEN); a = BigDecimal.valueOf(5).add(sqrt29) .divide(sqrt2, BigDecimal.ROUND_HALF_EVEN); b = BigDecimal.valueOf(5).multiply(sqrt29) .add(BigDecimal.valueOf(11).multiply(sqrt6)) .setScale(scale, BigDecimal.ROUND_HALF_EVEN); c = BigDecimal.valueOf(9) .add(BigDecimal.valueOf(3).multiply(sqrt6)) .divide(BigDecimal.valueOf(4), scale, BigDecimal.ROUND_HALF_EVEN); d = BigDecimal.valueOf(5) .add(BigDecimal.valueOf(3).multiply(sqrt6)) .divide(BigDecimal.valueOf(4), scale, BigDecimal.ROUND_HALF_EVEN); e = BigFunctions.sqrt(c, scale) .add(BigFunctions.sqrt(d, scale)); lnArg = BigFunctions.intPower(a, 3, scale) .multiply(b) .multiply(BigFunctions.intPower(e, 6, scale)) .setScale(scale, BigDecimal.ROUND_HALF_EVEN); pi = term.multiply(BigFunctions.ln(lnArg, scale)) .setScale(digits, BigDecimal.ROUND_HALF_EVEN); System.out.println(digits + " digits: " + pi); } /** * Main. * @param args the array of program arguments */ public static void main(String args[]) { PiRamanujan formulas = new PiRamanujan(); try { formulas.compute(); } catch(Exception ex) { System.out.println("ERROR: " + ex.getMessage()); } } } Output 15 digits: 3.141592653589793 16 digits: 3.1415926535897931 18 digits: 3.141592653589793238 22 digits: 3.1415926535897932384626 31 digits: 3.1415926535897932384626433832794 To help ensure the accuracy of the last digit of each formula's estimate of p , the program computes with a scale that is greater than the purported number of digits of accuracy. In the output shown in Listing 13-1, the last digit of the 16-digit result and of the 31-digit result is each off by 1 (the digits should be 2 and 5, respectively). |
Top |