// Big_math.java generate Pi, e to 100 fraction bits (error<1/2^100) // and a few other constants and functions // sqrt, sin, cos, atan, exp import java.math.BigDecimal; public class Big_math { BigDecimal epsilon; // based on desired precision BigDecimal natural_e; BigDecimal pi, npi; BigDecimal twopi; BigDecimal halfpi; BigDecimal fourthpi; BigDecimal rfact[] = new BigDecimal[50]; // reciprocal factorial about prec/2 BigDecimal zero = new BigDecimal(0.0); BigDecimal one = new BigDecimal(1.0); BigDecimal two = new BigDecimal(2.0); BigDecimal half = new BigDecimal("0.5"); int prec = 100; // digits // precision in bits = about 3.32 precision in digits public Big_math() // constructor { BigDecimal tmp; System.out.println("Big_math constructing"); // "constants" needed by other functions and users natural_e = naturalE(prec); /* precision */ System.out.println("natural_e="+natural_e); epsilon = half.pow(prec); System.out.println("epsilon="+epsilon); // precompute reciprocal factorials for for future use */ rfact[0] = new BigDecimal(1.0); rfact[1] = new BigDecimal(1.0); rfact[2] = half; for(int i=3; i<50; i++) { rfact[i] = rfact[i-1].divide(new BigDecimal((double)i),prec, BigDecimal.ROUND_DOWN); } System.out.println("rfact[49]="+rfact[49]); // precompute pi, pi/4, pi/2, 2pi for future use */ pi = Npi(); System.out.println("pi="+pi); halfpi = pi.multiply(half); System.out.println("halfpi="+halfpi); fourthpi = halfpi.multiply(half); System.out.println("fourthpi="+fourthpi); System.out.println("Big_math constructed"); } public BigDecimal factorial(BigDecimal n) { if(n.compareTo(new BigDecimal("1"))<=0) return new BigDecimal("1"); return n.multiply(factorial(n.subtract(new BigDecimal("1")))); } public BigDecimal sqrt(BigDecimal x) { BigDecimal y = new BigDecimal("1"); BigDecimal yn = y; BigDecimal xs = x.add(epsilon); for(int i=0; i<25; i++) { yn = (y.add(xs.divide(y,BigDecimal.ROUND_DOWN))).multiply(half); yn = yn.setScale(prec,BigDecimal.ROUND_DOWN); if(((yn.subtract(y)).abs()).compareTo(epsilon)<=0) return yn; y = yn; } return yn; } public BigDecimal exp_series(BigDecimal x) // abs(x)<=0.5, prec digits { // prec digits returned BigDecimal fact = new BigDecimal("1"); // factorial BigDecimal xp = new BigDecimal("1"); // power of x BigDecimal y = new BigDecimal("1"); // sum of series on x int n; n = (2*prec)/3; for(int i=1; i0) // positive { while(x.compareTo(j.add(one))>0) { ep = ep.multiply(natural_e); j = j.add(one); } xc = x.subtract(j); y = ep.multiply(exp_series(xc)); y = y.setScale(prec,BigDecimal.ROUND_DOWN); return y; } else // negative { xp = x.negate(); while(xp.compareTo(j.add(one))>0) { ep = ep.multiply(natural_e); j = j.add(one); } xc = xp.subtract(j); y = ep.multiply(exp_series(xc)); y = y.setScale(prec,BigDecimal.ROUND_DOWN); return (one.add(epsilon)).divide(y, prec,BigDecimal.ROUND_DOWN); } } // end exp public BigDecimal sin(BigDecimal x) { BigDecimal y; BigDecimal xc; BigDecimal tpi = pi.multiply(new BigDecimal("2")); if(x.abs().compareTo(tpi) <0) return sin_series(x); xc = x; if(xc.compareTo(new BigDecimal("0"))>0) // positive { while(xc.compareTo(tpi)>0) { xc = xc.subtract(tpi); } y = sin_series(xc); y = y.setScale(prec,BigDecimal.ROUND_DOWN); return y; } else // negative { while(xc.compareTo(tpi)<0) { xc = xc.add(tpi); } y = sin_series(xc); return y.setScale(prec,BigDecimal.ROUND_DOWN); } } // end sin public BigDecimal cos(BigDecimal x) { return sin(x.add(halfpi)); } // end cos public BigDecimal sin_series(BigDecimal x) // abs(x)<=0.5, prec digits { // prec digits returned BigDecimal fact = new BigDecimal("1"); // factorial BigDecimal xp = x; // power of x BigDecimal y = x; // sum of series on x int n; n = (2*prec)/3; for(int i=3; i0) break; sum = sum.add(one.divide(fact, prec_dig, BigDecimal.ROUND_DOWN)); } return sum; } } // end class Big_math