1*a164e4c8SXin Li /* 2*a164e4c8SXin Li * Copyright (C) 2015 The Android Open Source Project 3*a164e4c8SXin Li * 4*a164e4c8SXin Li * Licensed under the Apache License, Version 2.0 (the "License"); 5*a164e4c8SXin Li * you may not use this file except in compliance with the License. 6*a164e4c8SXin Li * You may obtain a copy of the License at 7*a164e4c8SXin Li * 8*a164e4c8SXin Li * http://www.apache.org/licenses/LICENSE-2.0 9*a164e4c8SXin Li * 10*a164e4c8SXin Li * Unless required by applicable law or agreed to in writing, software 11*a164e4c8SXin Li * distributed under the License is distributed on an "AS IS" BASIS, 12*a164e4c8SXin Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*a164e4c8SXin Li * See the License for the specific language governing permissions and 14*a164e4c8SXin Li * limitations under the License. 15*a164e4c8SXin Li */ 16*a164e4c8SXin Li 17*a164e4c8SXin Li /* 18*a164e4c8SXin Li * The above license covers additions and changes by AOSP authors. 19*a164e4c8SXin Li * The original code is licensed as follows: 20*a164e4c8SXin Li */ 21*a164e4c8SXin Li 22*a164e4c8SXin Li // 23*a164e4c8SXin Li // Copyright (c) 1999, Silicon Graphics, Inc. -- ALL RIGHTS RESERVED 24*a164e4c8SXin Li // 25*a164e4c8SXin Li // Permission is granted free of charge to copy, modify, use and distribute 26*a164e4c8SXin Li // this software provided you include the entirety of this notice in all 27*a164e4c8SXin Li // copies made. 28*a164e4c8SXin Li // 29*a164e4c8SXin Li // THIS SOFTWARE IS PROVIDED ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY 30*a164e4c8SXin Li // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, 31*a164e4c8SXin Li // WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT 32*a164e4c8SXin Li // FOR A PARTICULAR PURPOSE OR NON-INFRINGING. SGI ASSUMES NO RISK AS TO THE 33*a164e4c8SXin Li // QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD THE SOFTWARE PROVE 34*a164e4c8SXin Li // DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY 35*a164e4c8SXin Li // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES 36*a164e4c8SXin Li // AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS 37*a164e4c8SXin Li // AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 38*a164e4c8SXin Li // 39*a164e4c8SXin Li // UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING, 40*a164e4c8SXin Li // WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY), CONTRACT, OR 41*a164e4c8SXin Li // OTHERWISE, SHALL SGI BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, 42*a164e4c8SXin Li // INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER WITH RESPECT TO THE 43*a164e4c8SXin Li // SOFTWARE INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK 44*a164e4c8SXin Li // STOPPAGE, LOSS OF DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL 45*a164e4c8SXin Li // OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SGI SHALL HAVE BEEN INFORMED OF 46*a164e4c8SXin Li // THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT 47*a164e4c8SXin Li // APPLY TO LIABILITY RESULTING FROM SGI's NEGLIGENCE TO THE EXTENT APPLICABLE 48*a164e4c8SXin Li // LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE 49*a164e4c8SXin Li // EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT 50*a164e4c8SXin Li // EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 51*a164e4c8SXin Li // 52*a164e4c8SXin Li // These license terms shall be governed by and construed in accordance with 53*a164e4c8SXin Li // the laws of the United States and the State of California as applied to 54*a164e4c8SXin Li // agreements entered into and to be performed entirely within California 55*a164e4c8SXin Li // between California residents. Any litigation relating to these license 56*a164e4c8SXin Li // terms shall be subject to the exclusive jurisdiction of the Federal Courts 57*a164e4c8SXin Li // of the Northern District of California (or, absent subject matter 58*a164e4c8SXin Li // jurisdiction in such courts, the courts of the State of California), with 59*a164e4c8SXin Li // venue lying exclusively in Santa Clara County, California. 60*a164e4c8SXin Li 61*a164e4c8SXin Li // Copyright (c) 2001-2004, Hewlett-Packard Development Company, L.P. 62*a164e4c8SXin Li // 63*a164e4c8SXin Li // Permission is granted free of charge to copy, modify, use and distribute 64*a164e4c8SXin Li // this software provided you include the entirety of this notice in all 65*a164e4c8SXin Li // copies made. 66*a164e4c8SXin Li // 67*a164e4c8SXin Li // THIS SOFTWARE IS PROVIDED ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY 68*a164e4c8SXin Li // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, 69*a164e4c8SXin Li // WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT 70*a164e4c8SXin Li // FOR A PARTICULAR PURPOSE OR NON-INFRINGING. HEWLETT-PACKARD ASSUMES 71*a164e4c8SXin Li // NO RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. 72*a164e4c8SXin Li // SHOULD THE SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, 73*a164e4c8SXin Li // HEWLETT-PACKARD ASSUMES NO COST OR LIABILITY FOR ANY 74*a164e4c8SXin Li // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES 75*a164e4c8SXin Li // AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS 76*a164e4c8SXin Li // AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 77*a164e4c8SXin Li // 78*a164e4c8SXin Li // UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING, 79*a164e4c8SXin Li // WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY), CONTRACT, OR 80*a164e4c8SXin Li // OTHERWISE, SHALL HEWLETT-PACKARD BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, 81*a164e4c8SXin Li // INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER WITH RESPECT TO THE 82*a164e4c8SXin Li // SOFTWARE INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK 83*a164e4c8SXin Li // STOPPAGE, LOSS OF DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL 84*a164e4c8SXin Li // OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF HEWLETT-PACKARD SHALL 85*a164e4c8SXin Li // HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. 86*a164e4c8SXin Li // THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY RESULTING 87*a164e4c8SXin Li // FROM HEWLETT-PACKARD's NEGLIGENCE TO THE EXTENT APPLICABLE 88*a164e4c8SXin Li // LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE 89*a164e4c8SXin Li // EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT 90*a164e4c8SXin Li // EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 91*a164e4c8SXin Li // 92*a164e4c8SXin Li 93*a164e4c8SXin Li // Added valueOf(string, radix), fixed some documentation comments. 94*a164e4c8SXin Li // [email protected] 1/12/2001 95*a164e4c8SXin Li // Fixed a serious typo in inv_CR(): For negative arguments it produced 96*a164e4c8SXin Li // the wrong sign. This affected the sign of divisions. 97*a164e4c8SXin Li // Added byteValue and fixed some comments. [email protected] 12/17/2002 98*a164e4c8SXin Li // Added toStringFloatRep. [email protected] 4/1/2004 99*a164e4c8SXin Li // Added get_appr() synchronization to allow access from multiple threads 100*a164e4c8SXin Li // [email protected] 4/25/2014 101*a164e4c8SXin Li // Changed cos() prescaling to avoid logarithmic depth tree. 102*a164e4c8SXin Li // [email protected] 6/30/2014 103*a164e4c8SXin Li // Added explicit asin() implementation. Remove one. Add ZERO and ONE and 104*a164e4c8SXin Li // make them public. [email protected] 5/21/2015 105*a164e4c8SXin Li // Added Gauss-Legendre PI implementation. Removed two. 106*a164e4c8SXin Li // [email protected] 4/12/2016 107*a164e4c8SXin Li // Fix shift operation in doubleValue. That produced incorrect values for 108*a164e4c8SXin Li // large negative exponents. 109*a164e4c8SXin Li // Don't negate argument and compute inverse for exp(). That causes severe 110*a164e4c8SXin Li // performance problems for (-huge).exp() 111*a164e4c8SXin Li // [email protected] 8/21/2017 112*a164e4c8SXin Li // Have comparison check for interruption. [email protected] 10/31/2017 113*a164e4c8SXin Li // Fix precision overflow issue in most general compareTo function. 114*a164e4c8SXin Li // Fix a couple of unused variable bugs. Notably selector_sign was 115*a164e4c8SXin Li // accidentally locally redeclared. (This turns out to be safe but useless.) 116*a164e4c8SXin Li // [email protected] 11/20/2018. 117*a164e4c8SXin Li // Fix an exception-safety issue in gl_pi_CR.approximate. 118*a164e4c8SXin Li // [email protected] 3/3/2019. 119*a164e4c8SXin Li // Near-overflow floating point exponents were not handled correctly in 120*a164e4c8SXin Li // doubleValue(). Fixed. 121*a164e4c8SXin Li // [email protected] 7/23/2019. 122*a164e4c8SXin Li 123*a164e4c8SXin Li package com.hp.creals; 124*a164e4c8SXin Li 125*a164e4c8SXin Li import java.math.BigInteger; 126*a164e4c8SXin Li import java.util.ArrayList; 127*a164e4c8SXin Li 128*a164e4c8SXin Li /** 129*a164e4c8SXin Li * Constructive real numbers, also known as recursive, or computable reals. 130*a164e4c8SXin Li * Each recursive real number is represented as an object that provides an 131*a164e4c8SXin Li * approximation function for the real number. 132*a164e4c8SXin Li * The approximation function guarantees that the generated approximation 133*a164e4c8SXin Li * is accurate to the specified precision. 134*a164e4c8SXin Li * Arithmetic operations on constructive reals produce new such objects; 135*a164e4c8SXin Li * they typically do not perform any real computation. 136*a164e4c8SXin Li * In this sense, arithmetic computations are exact: They produce 137*a164e4c8SXin Li * a description which describes the exact answer, and can be used to 138*a164e4c8SXin Li * later approximate it to arbitrary precision. 139*a164e4c8SXin Li * <P> 140*a164e4c8SXin Li * When approximations are generated, <I>e.g.</i> for output, they are 141*a164e4c8SXin Li * accurate to the requested precision; no cumulative rounding errors 142*a164e4c8SXin Li * are visible. 143*a164e4c8SXin Li * In order to achieve this precision, the approximation function will often 144*a164e4c8SXin Li * need to approximate subexpressions to greater precision than was originally 145*a164e4c8SXin Li * demanded. Thus the approximation of a constructive real number 146*a164e4c8SXin Li * generated through a complex sequence of operations may eventually require 147*a164e4c8SXin Li * evaluation to very high precision. This usually makes such computations 148*a164e4c8SXin Li * prohibitively expensive for large numerical problems. 149*a164e4c8SXin Li * But it is perfectly appropriate for use in a desk calculator, 150*a164e4c8SXin Li * for small numerical problems, for the evaluation of expressions 151*a164e4c8SXin Li * computated by a symbolic algebra system, for testing of accuracy claims 152*a164e4c8SXin Li * for floating point code on small inputs, or the like. 153*a164e4c8SXin Li * <P> 154*a164e4c8SXin Li * We expect that the vast majority of uses will ignore the particular 155*a164e4c8SXin Li * implementation, and the member functons <TT>approximate</tt> 156*a164e4c8SXin Li * and <TT>get_appr</tt>. Such applications will treat <TT>CR</tt> as 157*a164e4c8SXin Li * a conventional numerical type, with an interface modelled on 158*a164e4c8SXin Li * <TT>java.math.BigInteger</tt>. No subclasses of <TT>CR</tt> 159*a164e4c8SXin Li * will be explicitly mentioned by such a program. 160*a164e4c8SXin Li * <P> 161*a164e4c8SXin Li * All standard arithmetic operations, as well as a few algebraic 162*a164e4c8SXin Li * and transcendal functions are provided. Constructive reals are 163*a164e4c8SXin Li * immutable; thus all of these operations return a new constructive real. 164*a164e4c8SXin Li * <P> 165*a164e4c8SXin Li * A few uses will require explicit construction of approximation functions. 166*a164e4c8SXin Li * The requires the construction of a subclass of <TT>CR</tt> with 167*a164e4c8SXin Li * an overridden <TT>approximate</tt> function. Note that <TT>approximate</tt> 168*a164e4c8SXin Li * should only be defined, but never called. <TT>get_appr</tt> 169*a164e4c8SXin Li * provides the same functionality, but adds the caching necessary to obtain 170*a164e4c8SXin Li * reasonable performance. 171*a164e4c8SXin Li * <P> 172*a164e4c8SXin Li * Any operation may throw <TT>com.hp.creals.AbortedException</tt> if the thread 173*a164e4c8SXin Li * in which it is executing is interrupted. (<TT>InterruptedException</tt> 174*a164e4c8SXin Li * cannot be used for this purpose, since CR inherits from <TT>Number</tt>.) 175*a164e4c8SXin Li * <P> 176*a164e4c8SXin Li * Any operation may also throw <TT>com.hp.creals.PrecisionOverflowException</tt> 177*a164e4c8SXin Li * If the precision request generated during any subcalculation overflows 178*a164e4c8SXin Li * a 28-bit integer. (This should be extremely unlikely, except as an 179*a164e4c8SXin Li * outcome of a division by zero, or other erroneous computation.) 180*a164e4c8SXin Li * 181*a164e4c8SXin Li */ 182*a164e4c8SXin Li public abstract class CR extends Number { 183*a164e4c8SXin Li // CR is the basic representation of a number. 184*a164e4c8SXin Li // Abstractly this is a function for computing an approximation 185*a164e4c8SXin Li // plus the current best approximation. 186*a164e4c8SXin Li // We could do without the latter, but that would 187*a164e4c8SXin Li // be atrociously slow. 188*a164e4c8SXin Li 189*a164e4c8SXin Li /** 190*a164e4c8SXin Li * Indicates a constructive real operation was interrupted. 191*a164e4c8SXin Li * Most constructive real operations may throw such an exception. 192*a164e4c8SXin Li * This is unchecked, since Number methods may not raise checked 193*a164e4c8SXin Li * exceptions. 194*a164e4c8SXin Li */ 195*a164e4c8SXin Li public static class AbortedException extends RuntimeException { AbortedException()196*a164e4c8SXin Li public AbortedException() { super(); } AbortedException(String s)197*a164e4c8SXin Li public AbortedException(String s) { super(s); } 198*a164e4c8SXin Li } 199*a164e4c8SXin Li 200*a164e4c8SXin Li /** 201*a164e4c8SXin Li * Indicates that the number of bits of precision requested by 202*a164e4c8SXin Li * a computation on constructive reals required more than 28 bits, 203*a164e4c8SXin Li * and was thus in danger of overflowing an int. 204*a164e4c8SXin Li * This is likely to be a symptom of a diverging computation, 205*a164e4c8SXin Li * <I>e.g.</i> division by zero. 206*a164e4c8SXin Li */ 207*a164e4c8SXin Li public static class PrecisionOverflowException extends RuntimeException { PrecisionOverflowException()208*a164e4c8SXin Li public PrecisionOverflowException() { super(); } PrecisionOverflowException(String s)209*a164e4c8SXin Li public PrecisionOverflowException(String s) { super(s); } 210*a164e4c8SXin Li } 211*a164e4c8SXin Li 212*a164e4c8SXin Li // First some frequently used constants, so we don't have to 213*a164e4c8SXin Li // recompute these all over the place. 214*a164e4c8SXin Li static final BigInteger big0 = BigInteger.ZERO; 215*a164e4c8SXin Li static final BigInteger big1 = BigInteger.ONE; 216*a164e4c8SXin Li static final BigInteger bigm1 = BigInteger.valueOf(-1); 217*a164e4c8SXin Li static final BigInteger big2 = BigInteger.valueOf(2); 218*a164e4c8SXin Li static final BigInteger bigm2 = BigInteger.valueOf(-2); 219*a164e4c8SXin Li static final BigInteger big3 = BigInteger.valueOf(3); 220*a164e4c8SXin Li static final BigInteger big6 = BigInteger.valueOf(6); 221*a164e4c8SXin Li static final BigInteger big8 = BigInteger.valueOf(8); 222*a164e4c8SXin Li static final BigInteger big10 = BigInteger.TEN; 223*a164e4c8SXin Li static final BigInteger big750 = BigInteger.valueOf(750); 224*a164e4c8SXin Li static final BigInteger bigm750 = BigInteger.valueOf(-750); 225*a164e4c8SXin Li 226*a164e4c8SXin Li /** 227*a164e4c8SXin Li * Setting this to true requests that all computations be aborted by 228*a164e4c8SXin Li * throwing AbortedException. Must be rest to false before any further 229*a164e4c8SXin Li * computation. Ideally Thread.interrupt() should be used instead, but 230*a164e4c8SXin Li * that doesn't appear to be consistently supported by browser VMs. 231*a164e4c8SXin Li */ 232*a164e4c8SXin Li public volatile static boolean please_stop = false; 233*a164e4c8SXin Li 234*a164e4c8SXin Li /** 235*a164e4c8SXin Li * Must be defined in subclasses of <TT>CR</tt>. 236*a164e4c8SXin Li * Most users can ignore the existence of this method, and will 237*a164e4c8SXin Li * not ever need to define a <TT>CR</tt> subclass. 238*a164e4c8SXin Li * Returns value / 2 ** precision rounded to an integer. 239*a164e4c8SXin Li * The error in the result is strictly < 1. 240*a164e4c8SXin Li * Informally, approximate(n) gives a scaled approximation 241*a164e4c8SXin Li * accurate to 2**n. 242*a164e4c8SXin Li * Implementations may safely assume that precision is 243*a164e4c8SXin Li * at least a factor of 8 away from overflow. 244*a164e4c8SXin Li * Called only with the lock on the <TT>CR</tt> object 245*a164e4c8SXin Li * already held. 246*a164e4c8SXin Li */ approximate(int precision)247*a164e4c8SXin Li protected abstract BigInteger approximate(int precision); 248*a164e4c8SXin Li transient int min_prec; 249*a164e4c8SXin Li // The smallest precision value with which the above 250*a164e4c8SXin Li // has been called. 251*a164e4c8SXin Li transient BigInteger max_appr; 252*a164e4c8SXin Li // The scaled approximation corresponding to min_prec. 253*a164e4c8SXin Li transient boolean appr_valid = false; 254*a164e4c8SXin Li // min_prec and max_val are valid. 255*a164e4c8SXin Li 256*a164e4c8SXin Li // Helper functions bound_log2(int n)257*a164e4c8SXin Li static int bound_log2(int n) { 258*a164e4c8SXin Li int abs_n = Math.abs(n); 259*a164e4c8SXin Li return (int)Math.ceil(Math.log((double)(abs_n + 1))/Math.log(2.0)); 260*a164e4c8SXin Li } 261*a164e4c8SXin Li // Check that a precision is at least a factor of 8 away from 262*a164e4c8SXin Li // overflowng the integer used to hold a precision spec. 263*a164e4c8SXin Li // We generally perform this check early on, and then convince 264*a164e4c8SXin Li // ourselves that none of the operations performed on precisions 265*a164e4c8SXin Li // inside a function can generate an overflow. check_prec(int n)266*a164e4c8SXin Li static void check_prec(int n) { 267*a164e4c8SXin Li int high = n >> 28; 268*a164e4c8SXin Li // if n is not in danger of overflowing, then the 4 high order 269*a164e4c8SXin Li // bits should be identical. Thus high is either 0 or -1. 270*a164e4c8SXin Li // The rest of this is to test for either of those in a way 271*a164e4c8SXin Li // that should be as cheap as possible. 272*a164e4c8SXin Li int high_shifted = n >> 29; 273*a164e4c8SXin Li if (0 != (high ^ high_shifted)) { 274*a164e4c8SXin Li throw new PrecisionOverflowException(); 275*a164e4c8SXin Li } 276*a164e4c8SXin Li } 277*a164e4c8SXin Li 278*a164e4c8SXin Li /** 279*a164e4c8SXin Li * The constructive real number corresponding to a 280*a164e4c8SXin Li * <TT>BigInteger</tt>. 281*a164e4c8SXin Li */ valueOf(BigInteger n)282*a164e4c8SXin Li public static CR valueOf(BigInteger n) { 283*a164e4c8SXin Li return new int_CR(n); 284*a164e4c8SXin Li } 285*a164e4c8SXin Li 286*a164e4c8SXin Li /** 287*a164e4c8SXin Li * The constructive real number corresponding to a 288*a164e4c8SXin Li * Java <TT>int</tt>. 289*a164e4c8SXin Li */ valueOf(int n)290*a164e4c8SXin Li public static CR valueOf(int n) { 291*a164e4c8SXin Li return valueOf(BigInteger.valueOf(n)); 292*a164e4c8SXin Li } 293*a164e4c8SXin Li 294*a164e4c8SXin Li /** 295*a164e4c8SXin Li * The constructive real number corresponding to a 296*a164e4c8SXin Li * Java <TT>long</tt>. 297*a164e4c8SXin Li */ valueOf(long n)298*a164e4c8SXin Li public static CR valueOf(long n) { 299*a164e4c8SXin Li return valueOf(BigInteger.valueOf(n)); 300*a164e4c8SXin Li } 301*a164e4c8SXin Li 302*a164e4c8SXin Li /** 303*a164e4c8SXin Li * The constructive real number corresponding to a 304*a164e4c8SXin Li * Java <TT>double</tt>. 305*a164e4c8SXin Li * The result is undefined if argument is infinite or NaN. 306*a164e4c8SXin Li */ valueOf(double n)307*a164e4c8SXin Li public static CR valueOf(double n) { 308*a164e4c8SXin Li if (Double.isNaN(n)) throw new ArithmeticException("Nan argument"); 309*a164e4c8SXin Li if (Double.isInfinite(n)) { 310*a164e4c8SXin Li throw new ArithmeticException("Infinite argument"); 311*a164e4c8SXin Li } 312*a164e4c8SXin Li boolean negative = (n < 0.0); 313*a164e4c8SXin Li long bits = Double.doubleToLongBits(Math.abs(n)); 314*a164e4c8SXin Li long mantissa = (bits & 0xfffffffffffffL); 315*a164e4c8SXin Li int biased_exp = (int)(bits >> 52); 316*a164e4c8SXin Li int exp = biased_exp - 1075; 317*a164e4c8SXin Li if (biased_exp != 0) { 318*a164e4c8SXin Li mantissa += (1L << 52); 319*a164e4c8SXin Li } else { 320*a164e4c8SXin Li mantissa <<= 1; 321*a164e4c8SXin Li } 322*a164e4c8SXin Li CR result = valueOf(mantissa).shiftLeft(exp); 323*a164e4c8SXin Li if (negative) result = result.negate(); 324*a164e4c8SXin Li return result; 325*a164e4c8SXin Li } 326*a164e4c8SXin Li 327*a164e4c8SXin Li /** 328*a164e4c8SXin Li * The constructive real number corresponding to a 329*a164e4c8SXin Li * Java <TT>float</tt>. 330*a164e4c8SXin Li * The result is undefined if argument is infinite or NaN. 331*a164e4c8SXin Li */ valueOf(float n)332*a164e4c8SXin Li public static CR valueOf(float n) { 333*a164e4c8SXin Li return valueOf((double) n); 334*a164e4c8SXin Li } 335*a164e4c8SXin Li 336*a164e4c8SXin Li public static CR ZERO = valueOf(0); 337*a164e4c8SXin Li public static CR ONE = valueOf(1); 338*a164e4c8SXin Li 339*a164e4c8SXin Li // Multiply k by 2**n. shift(BigInteger k, int n)340*a164e4c8SXin Li static BigInteger shift(BigInteger k, int n) { 341*a164e4c8SXin Li if (n == 0) return k; 342*a164e4c8SXin Li if (n < 0) return k.shiftRight(-n); 343*a164e4c8SXin Li return k.shiftLeft(n); 344*a164e4c8SXin Li } 345*a164e4c8SXin Li 346*a164e4c8SXin Li // Multiply by 2**n, rounding result scale(BigInteger k, int n)347*a164e4c8SXin Li static BigInteger scale(BigInteger k, int n) { 348*a164e4c8SXin Li if (n >= 0) { 349*a164e4c8SXin Li return k.shiftLeft(n); 350*a164e4c8SXin Li } else { 351*a164e4c8SXin Li BigInteger adj_k = shift(k, n+1).add(big1); 352*a164e4c8SXin Li return adj_k.shiftRight(1); 353*a164e4c8SXin Li } 354*a164e4c8SXin Li } 355*a164e4c8SXin Li 356*a164e4c8SXin Li // Identical to approximate(), but maintain and update cache. 357*a164e4c8SXin Li /** 358*a164e4c8SXin Li * Returns value / 2 ** prec rounded to an integer. 359*a164e4c8SXin Li * The error in the result is strictly < 1. 360*a164e4c8SXin Li * Produces the same answer as <TT>approximate</tt>, but uses and 361*a164e4c8SXin Li * maintains a cached approximation. 362*a164e4c8SXin Li * Normally not overridden, and called only from <TT>approximate</tt> 363*a164e4c8SXin Li * methods in subclasses. Not needed if the provided operations 364*a164e4c8SXin Li * on constructive reals suffice. 365*a164e4c8SXin Li */ get_appr(int precision)366*a164e4c8SXin Li public synchronized BigInteger get_appr(int precision) { 367*a164e4c8SXin Li check_prec(precision); 368*a164e4c8SXin Li if (appr_valid && precision >= min_prec) { 369*a164e4c8SXin Li return scale(max_appr, min_prec - precision); 370*a164e4c8SXin Li } else { 371*a164e4c8SXin Li BigInteger result = approximate(precision); 372*a164e4c8SXin Li min_prec = precision; 373*a164e4c8SXin Li max_appr = result; 374*a164e4c8SXin Li appr_valid = true; 375*a164e4c8SXin Li return result; 376*a164e4c8SXin Li } 377*a164e4c8SXin Li } 378*a164e4c8SXin Li 379*a164e4c8SXin Li // Return the position of the msd. 380*a164e4c8SXin Li // If x.msd() == n then 381*a164e4c8SXin Li // 2**(n-1) < abs(x) < 2**(n+1) 382*a164e4c8SXin Li // This initial version assumes that max_appr is valid 383*a164e4c8SXin Li // and sufficiently removed from zero 384*a164e4c8SXin Li // that the msd is determined. known_msd()385*a164e4c8SXin Li int known_msd() { 386*a164e4c8SXin Li int first_digit; 387*a164e4c8SXin Li int length; 388*a164e4c8SXin Li if (max_appr.signum() >= 0) { 389*a164e4c8SXin Li length = max_appr.bitLength(); 390*a164e4c8SXin Li } else { 391*a164e4c8SXin Li length = max_appr.negate().bitLength(); 392*a164e4c8SXin Li } 393*a164e4c8SXin Li first_digit = min_prec + length - 1; 394*a164e4c8SXin Li return first_digit; 395*a164e4c8SXin Li } 396*a164e4c8SXin Li 397*a164e4c8SXin Li // This version may return Integer.MIN_VALUE if the correct 398*a164e4c8SXin Li // answer is < n. msd(int n)399*a164e4c8SXin Li int msd(int n) { 400*a164e4c8SXin Li if (!appr_valid || 401*a164e4c8SXin Li max_appr.compareTo(big1) <= 0 402*a164e4c8SXin Li && max_appr.compareTo(bigm1) >= 0) { 403*a164e4c8SXin Li get_appr(n - 1); 404*a164e4c8SXin Li if (max_appr.abs().compareTo(big1) <= 0) { 405*a164e4c8SXin Li // msd could still be arbitrarily far to the right. 406*a164e4c8SXin Li return Integer.MIN_VALUE; 407*a164e4c8SXin Li } 408*a164e4c8SXin Li } 409*a164e4c8SXin Li return known_msd(); 410*a164e4c8SXin Li } 411*a164e4c8SXin Li 412*a164e4c8SXin Li 413*a164e4c8SXin Li // Functionally equivalent, but iteratively evaluates to higher 414*a164e4c8SXin Li // precision. iter_msd(int n)415*a164e4c8SXin Li int iter_msd(int n) 416*a164e4c8SXin Li { 417*a164e4c8SXin Li int prec = 0; 418*a164e4c8SXin Li 419*a164e4c8SXin Li for (; prec > n + 30; prec = (prec * 3)/2 - 16) { 420*a164e4c8SXin Li int msd = msd(prec); 421*a164e4c8SXin Li if (msd != Integer.MIN_VALUE) return msd; 422*a164e4c8SXin Li check_prec(prec); 423*a164e4c8SXin Li if (Thread.interrupted() || please_stop) { 424*a164e4c8SXin Li throw new AbortedException(); 425*a164e4c8SXin Li } 426*a164e4c8SXin Li } 427*a164e4c8SXin Li return msd(n); 428*a164e4c8SXin Li } 429*a164e4c8SXin Li 430*a164e4c8SXin Li // This version returns a correct answer eventually, except 431*a164e4c8SXin Li // that it loops forever (or throws an exception when the 432*a164e4c8SXin Li // requested precision overflows) if this constructive real is zero. msd()433*a164e4c8SXin Li int msd() { 434*a164e4c8SXin Li return iter_msd(Integer.MIN_VALUE); 435*a164e4c8SXin Li } 436*a164e4c8SXin Li 437*a164e4c8SXin Li // A helper function for toString. 438*a164e4c8SXin Li // Generate a String containing n zeroes. zeroes(int n)439*a164e4c8SXin Li private static String zeroes(int n) { 440*a164e4c8SXin Li char[] a = new char[n]; 441*a164e4c8SXin Li for (int i = 0; i < n; ++i) { 442*a164e4c8SXin Li a[i] = '0'; 443*a164e4c8SXin Li } 444*a164e4c8SXin Li return new String(a); 445*a164e4c8SXin Li } 446*a164e4c8SXin Li 447*a164e4c8SXin Li // Natural log of 2. Needed for some prescaling below. 448*a164e4c8SXin Li // ln(2) = 7ln(10/9) - 2ln(25/24) + 3ln(81/80) simple_ln()449*a164e4c8SXin Li CR simple_ln() { 450*a164e4c8SXin Li return new prescaled_ln_CR(this.subtract(ONE)); 451*a164e4c8SXin Li } 452*a164e4c8SXin Li static CR ten_ninths = valueOf(10).divide(valueOf(9)); 453*a164e4c8SXin Li static CR twentyfive_twentyfourths = valueOf(25).divide(valueOf(24)); 454*a164e4c8SXin Li static CR eightyone_eightyeths = valueOf(81).divide(valueOf(80)); 455*a164e4c8SXin Li static CR ln2_1 = valueOf(7).multiply(ten_ninths.simple_ln()); 456*a164e4c8SXin Li static CR ln2_2 = 457*a164e4c8SXin Li valueOf(2).multiply(twentyfive_twentyfourths.simple_ln()); 458*a164e4c8SXin Li static CR ln2_3 = valueOf(3).multiply(eightyone_eightyeths.simple_ln()); 459*a164e4c8SXin Li static CR ln2 = ln2_1.subtract(ln2_2).add(ln2_3); 460*a164e4c8SXin Li 461*a164e4c8SXin Li // Atan of integer reciprocal. Used for atan_PI. Could perhaps be made 462*a164e4c8SXin Li // public. atan_reciprocal(int n)463*a164e4c8SXin Li static CR atan_reciprocal(int n) { 464*a164e4c8SXin Li return new integral_atan_CR(n); 465*a164e4c8SXin Li } 466*a164e4c8SXin Li // Other constants used for PI computation. 467*a164e4c8SXin Li static CR four = valueOf(4); 468*a164e4c8SXin Li 469*a164e4c8SXin Li // Public operations. 470*a164e4c8SXin Li /** 471*a164e4c8SXin Li * Return 0 if x = y to within the indicated tolerance, 472*a164e4c8SXin Li * -1 if x < y, and +1 if x > y. If x and y are indeed 473*a164e4c8SXin Li * equal, it is guaranteed that 0 will be returned. If 474*a164e4c8SXin Li * they differ by less than the tolerance, anything 475*a164e4c8SXin Li * may happen. The tolerance allowed is 476*a164e4c8SXin Li * the maximum of (abs(this)+abs(x))*(2**r) and 2**a 477*a164e4c8SXin Li * @param x The other constructive real 478*a164e4c8SXin Li * @param r Relative tolerance in bits 479*a164e4c8SXin Li * @param a Absolute tolerance in bits 480*a164e4c8SXin Li */ compareTo(CR x, int r, int a)481*a164e4c8SXin Li public int compareTo(CR x, int r, int a) { 482*a164e4c8SXin Li int this_msd = iter_msd(a); 483*a164e4c8SXin Li int x_msd = x.iter_msd(this_msd > a? this_msd : a); 484*a164e4c8SXin Li int max_msd = (x_msd > this_msd? x_msd : this_msd); 485*a164e4c8SXin Li if (max_msd == Integer.MIN_VALUE) { 486*a164e4c8SXin Li return 0; 487*a164e4c8SXin Li } 488*a164e4c8SXin Li check_prec(r); 489*a164e4c8SXin Li int rel = max_msd + r; 490*a164e4c8SXin Li int abs_prec = (rel > a? rel : a); 491*a164e4c8SXin Li return compareTo(x, abs_prec); 492*a164e4c8SXin Li } 493*a164e4c8SXin Li 494*a164e4c8SXin Li /** 495*a164e4c8SXin Li * Approximate comparison with only an absolute tolerance. 496*a164e4c8SXin Li * Identical to the three argument version, but without a relative 497*a164e4c8SXin Li * tolerance. 498*a164e4c8SXin Li * Result is 0 if both constructive reals are equal, indeterminate 499*a164e4c8SXin Li * if they differ by less than 2**a. 500*a164e4c8SXin Li * 501*a164e4c8SXin Li * @param x The other constructive real 502*a164e4c8SXin Li * @param a Absolute tolerance in bits 503*a164e4c8SXin Li */ compareTo(CR x, int a)504*a164e4c8SXin Li public int compareTo(CR x, int a) { 505*a164e4c8SXin Li int needed_prec = a - 1; 506*a164e4c8SXin Li BigInteger this_appr = get_appr(needed_prec); 507*a164e4c8SXin Li BigInteger x_appr = x.get_appr(needed_prec); 508*a164e4c8SXin Li int comp1 = this_appr.compareTo(x_appr.add(big1)); 509*a164e4c8SXin Li if (comp1 > 0) return 1; 510*a164e4c8SXin Li int comp2 = this_appr.compareTo(x_appr.subtract(big1)); 511*a164e4c8SXin Li if (comp2 < 0) return -1; 512*a164e4c8SXin Li return 0; 513*a164e4c8SXin Li } 514*a164e4c8SXin Li 515*a164e4c8SXin Li /** 516*a164e4c8SXin Li * Return -1 if <TT>this < x</tt>, or +1 if <TT>this > x</tt>. 517*a164e4c8SXin Li * Should be called only if <TT>this != x</tt>. 518*a164e4c8SXin Li * If <TT>this == x</tt>, this will not terminate correctly; typically it 519*a164e4c8SXin Li * will run until it exhausts memory. 520*a164e4c8SXin Li * If the two constructive reals may be equal, the two or 3 argument 521*a164e4c8SXin Li * version of compareTo should be used. 522*a164e4c8SXin Li */ compareTo(CR x)523*a164e4c8SXin Li public int compareTo(CR x) { 524*a164e4c8SXin Li for (int a = -20; ; a *= 2) { 525*a164e4c8SXin Li check_prec(a); 526*a164e4c8SXin Li int result = compareTo(x, a); 527*a164e4c8SXin Li if (0 != result) return result; 528*a164e4c8SXin Li if (Thread.interrupted() || please_stop) { 529*a164e4c8SXin Li throw new AbortedException(); 530*a164e4c8SXin Li } 531*a164e4c8SXin Li } 532*a164e4c8SXin Li } 533*a164e4c8SXin Li 534*a164e4c8SXin Li /** 535*a164e4c8SXin Li * Equivalent to <TT>compareTo(CR.valueOf(0), a)</tt> 536*a164e4c8SXin Li */ signum(int a)537*a164e4c8SXin Li public int signum(int a) { 538*a164e4c8SXin Li if (appr_valid) { 539*a164e4c8SXin Li int quick_try = max_appr.signum(); 540*a164e4c8SXin Li if (0 != quick_try) return quick_try; 541*a164e4c8SXin Li } 542*a164e4c8SXin Li int needed_prec = a - 1; 543*a164e4c8SXin Li BigInteger this_appr = get_appr(needed_prec); 544*a164e4c8SXin Li return this_appr.signum(); 545*a164e4c8SXin Li } 546*a164e4c8SXin Li 547*a164e4c8SXin Li /** 548*a164e4c8SXin Li * Return -1 if negative, +1 if positive. 549*a164e4c8SXin Li * Should be called only if <TT>this != 0</tt>. 550*a164e4c8SXin Li * In the 0 case, this will not terminate correctly; typically it 551*a164e4c8SXin Li * will run until it exhausts memory. 552*a164e4c8SXin Li * If the two constructive reals may be equal, the one or two argument 553*a164e4c8SXin Li * version of signum should be used. 554*a164e4c8SXin Li */ signum()555*a164e4c8SXin Li public int signum() { 556*a164e4c8SXin Li for (int a = -20; ; a *= 2) { 557*a164e4c8SXin Li check_prec(a); 558*a164e4c8SXin Li int result = signum(a); 559*a164e4c8SXin Li if (0 != result) return result; 560*a164e4c8SXin Li if (Thread.interrupted() || please_stop) { 561*a164e4c8SXin Li throw new AbortedException(); 562*a164e4c8SXin Li } 563*a164e4c8SXin Li } 564*a164e4c8SXin Li } 565*a164e4c8SXin Li 566*a164e4c8SXin Li /** 567*a164e4c8SXin Li * Return the constructive real number corresponding to the given 568*a164e4c8SXin Li * textual representation and radix. 569*a164e4c8SXin Li * 570*a164e4c8SXin Li * @param s [-] digit* [. digit*] 571*a164e4c8SXin Li * @param radix 572*a164e4c8SXin Li */ 573*a164e4c8SXin Li valueOf(String s, int radix)574*a164e4c8SXin Li public static CR valueOf(String s, int radix) 575*a164e4c8SXin Li throws NumberFormatException { 576*a164e4c8SXin Li int len = s.length(); 577*a164e4c8SXin Li int start_pos = 0, point_pos; 578*a164e4c8SXin Li String fraction; 579*a164e4c8SXin Li while (s.charAt(start_pos) == ' ') ++start_pos; 580*a164e4c8SXin Li while (s.charAt(len - 1) == ' ') --len; 581*a164e4c8SXin Li point_pos = s.indexOf('.', start_pos); 582*a164e4c8SXin Li if (point_pos == -1) { 583*a164e4c8SXin Li point_pos = len; 584*a164e4c8SXin Li fraction = "0"; 585*a164e4c8SXin Li } else { 586*a164e4c8SXin Li fraction = s.substring(point_pos + 1, len); 587*a164e4c8SXin Li } 588*a164e4c8SXin Li String whole = s.substring(start_pos, point_pos); 589*a164e4c8SXin Li BigInteger scaled_result = new BigInteger(whole + fraction, radix); 590*a164e4c8SXin Li BigInteger divisor = BigInteger.valueOf(radix).pow(fraction.length()); 591*a164e4c8SXin Li return CR.valueOf(scaled_result).divide(CR.valueOf(divisor)); 592*a164e4c8SXin Li } 593*a164e4c8SXin Li 594*a164e4c8SXin Li /** 595*a164e4c8SXin Li * Return a textual representation accurate to <TT>n</tt> places 596*a164e4c8SXin Li * to the right of the decimal point. <TT>n</tt> must be nonnegative. 597*a164e4c8SXin Li * 598*a164e4c8SXin Li * @param n Number of digits (>= 0) included to the right of decimal point 599*a164e4c8SXin Li * @param radix Base ( >= 2, <= 16) for the resulting representation. 600*a164e4c8SXin Li */ toString(int n, int radix)601*a164e4c8SXin Li public String toString(int n, int radix) { 602*a164e4c8SXin Li CR scaled_CR; 603*a164e4c8SXin Li if (16 == radix) { 604*a164e4c8SXin Li scaled_CR = shiftLeft(4*n); 605*a164e4c8SXin Li } else { 606*a164e4c8SXin Li BigInteger scale_factor = BigInteger.valueOf(radix).pow(n); 607*a164e4c8SXin Li scaled_CR = multiply(new int_CR(scale_factor)); 608*a164e4c8SXin Li } 609*a164e4c8SXin Li BigInteger scaled_int = scaled_CR.get_appr(0); 610*a164e4c8SXin Li String scaled_string = scaled_int.abs().toString(radix); 611*a164e4c8SXin Li String result; 612*a164e4c8SXin Li if (0 == n) { 613*a164e4c8SXin Li result = scaled_string; 614*a164e4c8SXin Li } else { 615*a164e4c8SXin Li int len = scaled_string.length(); 616*a164e4c8SXin Li if (len <= n) { 617*a164e4c8SXin Li // Add sufficient leading zeroes 618*a164e4c8SXin Li String z = zeroes(n + 1 - len); 619*a164e4c8SXin Li scaled_string = z + scaled_string; 620*a164e4c8SXin Li len = n + 1; 621*a164e4c8SXin Li } 622*a164e4c8SXin Li String whole = scaled_string.substring(0, len - n); 623*a164e4c8SXin Li String fraction = scaled_string.substring(len - n); 624*a164e4c8SXin Li result = whole + "." + fraction; 625*a164e4c8SXin Li } 626*a164e4c8SXin Li if (scaled_int.signum() < 0) { 627*a164e4c8SXin Li result = "-" + result; 628*a164e4c8SXin Li } 629*a164e4c8SXin Li return result; 630*a164e4c8SXin Li } 631*a164e4c8SXin Li 632*a164e4c8SXin Li 633*a164e4c8SXin Li /** 634*a164e4c8SXin Li * Equivalent to <TT>toString(n,10)</tt> 635*a164e4c8SXin Li * 636*a164e4c8SXin Li * @param n Number of digits included to the right of decimal point 637*a164e4c8SXin Li */ toString(int n)638*a164e4c8SXin Li public String toString(int n) { 639*a164e4c8SXin Li return toString(n, 10); 640*a164e4c8SXin Li } 641*a164e4c8SXin Li 642*a164e4c8SXin Li /** 643*a164e4c8SXin Li * Equivalent to <TT>toString(10, 10)</tt> 644*a164e4c8SXin Li */ toString()645*a164e4c8SXin Li public String toString() { 646*a164e4c8SXin Li return toString(10); 647*a164e4c8SXin Li } 648*a164e4c8SXin Li 649*a164e4c8SXin Li static double doubleLog2 = Math.log(2.0); 650*a164e4c8SXin Li /** 651*a164e4c8SXin Li * Return a textual scientific notation representation accurate 652*a164e4c8SXin Li * to <TT>n</tt> places to the right of the decimal point. 653*a164e4c8SXin Li * <TT>n</tt> must be nonnegative. A value smaller than 654*a164e4c8SXin Li * <TT>radix</tt>**-<TT>m</tt> may be displayed as 0. 655*a164e4c8SXin Li * The <TT>mantissa</tt> component of the result is either "0" 656*a164e4c8SXin Li * or exactly <TT>n</tt> digits long. The <TT>sign</tt> 657*a164e4c8SXin Li * component is zero exactly when the mantissa is "0". 658*a164e4c8SXin Li * 659*a164e4c8SXin Li * @param n Number of digits (> 0) included to the right of decimal point. 660*a164e4c8SXin Li * @param radix Base ( ≥ 2, ≤ 16) for the resulting representation. 661*a164e4c8SXin Li * @param m Precision used to distinguish number from zero. 662*a164e4c8SXin Li * Expressed as a power of m. 663*a164e4c8SXin Li */ toStringFloatRep(int n, int radix, int m)664*a164e4c8SXin Li public StringFloatRep toStringFloatRep(int n, int radix, int m) { 665*a164e4c8SXin Li if (n <= 0) throw new ArithmeticException("Bad precision argument"); 666*a164e4c8SXin Li double log2_radix = Math.log((double)radix)/doubleLog2; 667*a164e4c8SXin Li BigInteger big_radix = BigInteger.valueOf(radix); 668*a164e4c8SXin Li long long_msd_prec = (long)(log2_radix * (double)m); 669*a164e4c8SXin Li if (long_msd_prec > (long)Integer.MAX_VALUE 670*a164e4c8SXin Li || long_msd_prec < (long)Integer.MIN_VALUE) 671*a164e4c8SXin Li throw new PrecisionOverflowException(); 672*a164e4c8SXin Li int msd_prec = (int)long_msd_prec; 673*a164e4c8SXin Li check_prec(msd_prec); 674*a164e4c8SXin Li int msd = iter_msd(msd_prec - 2); 675*a164e4c8SXin Li if (msd == Integer.MIN_VALUE) 676*a164e4c8SXin Li return new StringFloatRep(0, "0", radix, 0); 677*a164e4c8SXin Li int exponent = (int)Math.ceil((double)msd / log2_radix); 678*a164e4c8SXin Li // Guess for the exponent. Try to get it usually right. 679*a164e4c8SXin Li int scale_exp = exponent - n; 680*a164e4c8SXin Li CR scale; 681*a164e4c8SXin Li if (scale_exp > 0) { 682*a164e4c8SXin Li scale = CR.valueOf(big_radix.pow(scale_exp)).inverse(); 683*a164e4c8SXin Li } else { 684*a164e4c8SXin Li scale = CR.valueOf(big_radix.pow(-scale_exp)); 685*a164e4c8SXin Li } 686*a164e4c8SXin Li CR scaled_res = multiply(scale); 687*a164e4c8SXin Li BigInteger scaled_int = scaled_res.get_appr(0); 688*a164e4c8SXin Li int sign = scaled_int.signum(); 689*a164e4c8SXin Li String scaled_string = scaled_int.abs().toString(radix); 690*a164e4c8SXin Li while (scaled_string.length() < n) { 691*a164e4c8SXin Li // exponent was too large. Adjust. 692*a164e4c8SXin Li scaled_res = scaled_res.multiply(CR.valueOf(big_radix)); 693*a164e4c8SXin Li exponent -= 1; 694*a164e4c8SXin Li scaled_int = scaled_res.get_appr(0); 695*a164e4c8SXin Li sign = scaled_int.signum(); 696*a164e4c8SXin Li scaled_string = scaled_int.abs().toString(radix); 697*a164e4c8SXin Li } 698*a164e4c8SXin Li if (scaled_string.length() > n) { 699*a164e4c8SXin Li // exponent was too small. Adjust by truncating. 700*a164e4c8SXin Li exponent += (scaled_string.length() - n); 701*a164e4c8SXin Li scaled_string = scaled_string.substring(0, n); 702*a164e4c8SXin Li } 703*a164e4c8SXin Li return new StringFloatRep(sign, scaled_string, radix, exponent); 704*a164e4c8SXin Li } 705*a164e4c8SXin Li 706*a164e4c8SXin Li /** 707*a164e4c8SXin Li * Return a BigInteger which differs by less than one from the 708*a164e4c8SXin Li * constructive real. 709*a164e4c8SXin Li */ BigIntegerValue()710*a164e4c8SXin Li public BigInteger BigIntegerValue() { 711*a164e4c8SXin Li return get_appr(0); 712*a164e4c8SXin Li } 713*a164e4c8SXin Li 714*a164e4c8SXin Li /** 715*a164e4c8SXin Li * Return an int which differs by less than one from the 716*a164e4c8SXin Li * constructive real. Behavior on overflow is undefined. 717*a164e4c8SXin Li */ intValue()718*a164e4c8SXin Li public int intValue() { 719*a164e4c8SXin Li return BigIntegerValue().intValue(); 720*a164e4c8SXin Li } 721*a164e4c8SXin Li 722*a164e4c8SXin Li /** 723*a164e4c8SXin Li * Return an int which differs by less than one from the 724*a164e4c8SXin Li * constructive real. Behavior on overflow is undefined. 725*a164e4c8SXin Li */ byteValue()726*a164e4c8SXin Li public byte byteValue() { 727*a164e4c8SXin Li return BigIntegerValue().byteValue(); 728*a164e4c8SXin Li } 729*a164e4c8SXin Li 730*a164e4c8SXin Li /** 731*a164e4c8SXin Li * Return a long which differs by less than one from the 732*a164e4c8SXin Li * constructive real. Behavior on overflow is undefined. 733*a164e4c8SXin Li */ longValue()734*a164e4c8SXin Li public long longValue() { 735*a164e4c8SXin Li return BigIntegerValue().longValue(); 736*a164e4c8SXin Li } 737*a164e4c8SXin Li 738*a164e4c8SXin Li /** 739*a164e4c8SXin Li * Return a double which differs by less than one in the least 740*a164e4c8SXin Li * represented bit from the constructive real. 741*a164e4c8SXin Li * (We're in fact closer to round-to-nearest than that, but we can't and 742*a164e4c8SXin Li * don't promise correct rounding.) 743*a164e4c8SXin Li */ doubleValue()744*a164e4c8SXin Li public double doubleValue() { 745*a164e4c8SXin Li int my_msd = iter_msd(-1080 /* slightly > exp. range */); 746*a164e4c8SXin Li if (Integer.MIN_VALUE == my_msd) return 0.0; 747*a164e4c8SXin Li int needed_prec = my_msd - 60; 748*a164e4c8SXin Li double scaled_int = get_appr(needed_prec).doubleValue(); 749*a164e4c8SXin Li boolean may_underflow = (needed_prec < -1000); 750*a164e4c8SXin Li long scaled_int_rep = Double.doubleToLongBits(scaled_int); 751*a164e4c8SXin Li long exp_adj = may_underflow? needed_prec + 96 : needed_prec; 752*a164e4c8SXin Li long orig_exp = (scaled_int_rep >> 52) & 0x7ff; 753*a164e4c8SXin Li // Original unbiased exponent is > 50. Exp_adj > -1050. 754*a164e4c8SXin Li // Thus the sum must be > the smallest representable exponent 755*a164e4c8SXin Li // of -1023. 756*a164e4c8SXin Li if (orig_exp + exp_adj >= 0x7ff) { 757*a164e4c8SXin Li // Exponent overflowed. 758*a164e4c8SXin Li if (scaled_int < 0.0) { 759*a164e4c8SXin Li return Double.NEGATIVE_INFINITY; 760*a164e4c8SXin Li } else { 761*a164e4c8SXin Li return Double.POSITIVE_INFINITY; 762*a164e4c8SXin Li } 763*a164e4c8SXin Li } 764*a164e4c8SXin Li scaled_int_rep += exp_adj << 52; 765*a164e4c8SXin Li double result = Double.longBitsToDouble(scaled_int_rep); 766*a164e4c8SXin Li if (may_underflow) { 767*a164e4c8SXin Li // Exponent is too large by 96. Compensate, relying on fp arithmetic 768*a164e4c8SXin Li // to handle gradual underflow correctly. 769*a164e4c8SXin Li double two48 = (double)(1L << 48); 770*a164e4c8SXin Li return result/two48/two48; 771*a164e4c8SXin Li } else { 772*a164e4c8SXin Li return result; 773*a164e4c8SXin Li } 774*a164e4c8SXin Li } 775*a164e4c8SXin Li 776*a164e4c8SXin Li /** 777*a164e4c8SXin Li * Return a float which differs by less than one in the least 778*a164e4c8SXin Li * represented bit from the constructive real. 779*a164e4c8SXin Li */ floatValue()780*a164e4c8SXin Li public float floatValue() { 781*a164e4c8SXin Li return (float)doubleValue(); 782*a164e4c8SXin Li // Note that double-rounding is not a problem here, since we 783*a164e4c8SXin Li // cannot, and do not, guarantee correct rounding. 784*a164e4c8SXin Li } 785*a164e4c8SXin Li 786*a164e4c8SXin Li /** 787*a164e4c8SXin Li * Add two constructive reals. 788*a164e4c8SXin Li */ add(CR x)789*a164e4c8SXin Li public CR add(CR x) { 790*a164e4c8SXin Li return new add_CR(this, x); 791*a164e4c8SXin Li } 792*a164e4c8SXin Li 793*a164e4c8SXin Li /** 794*a164e4c8SXin Li * Multiply a constructive real by 2**n. 795*a164e4c8SXin Li * @param n shift count, may be negative 796*a164e4c8SXin Li */ shiftLeft(int n)797*a164e4c8SXin Li public CR shiftLeft(int n) { 798*a164e4c8SXin Li check_prec(n); 799*a164e4c8SXin Li return new shifted_CR(this, n); 800*a164e4c8SXin Li } 801*a164e4c8SXin Li 802*a164e4c8SXin Li /** 803*a164e4c8SXin Li * Multiply a constructive real by 2**(-n). 804*a164e4c8SXin Li * @param n shift count, may be negative 805*a164e4c8SXin Li */ shiftRight(int n)806*a164e4c8SXin Li public CR shiftRight(int n) { 807*a164e4c8SXin Li check_prec(n); 808*a164e4c8SXin Li return new shifted_CR(this, -n); 809*a164e4c8SXin Li } 810*a164e4c8SXin Li 811*a164e4c8SXin Li /** 812*a164e4c8SXin Li * Produce a constructive real equivalent to the original, assuming 813*a164e4c8SXin Li * the original was an integer. Undefined results if the original 814*a164e4c8SXin Li * was not an integer. Prevents evaluation of digits to the right 815*a164e4c8SXin Li * of the decimal point, and may thus improve performance. 816*a164e4c8SXin Li */ assumeInt()817*a164e4c8SXin Li public CR assumeInt() { 818*a164e4c8SXin Li return new assumed_int_CR(this); 819*a164e4c8SXin Li } 820*a164e4c8SXin Li 821*a164e4c8SXin Li /** 822*a164e4c8SXin Li * The additive inverse of a constructive real 823*a164e4c8SXin Li */ negate()824*a164e4c8SXin Li public CR negate() { 825*a164e4c8SXin Li return new neg_CR(this); 826*a164e4c8SXin Li } 827*a164e4c8SXin Li 828*a164e4c8SXin Li /** 829*a164e4c8SXin Li * The difference between two constructive reals 830*a164e4c8SXin Li */ subtract(CR x)831*a164e4c8SXin Li public CR subtract(CR x) { 832*a164e4c8SXin Li return new add_CR(this, x.negate()); 833*a164e4c8SXin Li } 834*a164e4c8SXin Li 835*a164e4c8SXin Li /** 836*a164e4c8SXin Li * The product of two constructive reals 837*a164e4c8SXin Li */ multiply(CR x)838*a164e4c8SXin Li public CR multiply(CR x) { 839*a164e4c8SXin Li return new mult_CR(this, x); 840*a164e4c8SXin Li } 841*a164e4c8SXin Li 842*a164e4c8SXin Li /** 843*a164e4c8SXin Li * The multiplicative inverse of a constructive real. 844*a164e4c8SXin Li * <TT>x.inverse()</tt> is equivalent to <TT>CR.valueOf(1).divide(x)</tt>. 845*a164e4c8SXin Li */ inverse()846*a164e4c8SXin Li public CR inverse() { 847*a164e4c8SXin Li return new inv_CR(this); 848*a164e4c8SXin Li } 849*a164e4c8SXin Li 850*a164e4c8SXin Li /** 851*a164e4c8SXin Li * The quotient of two constructive reals. 852*a164e4c8SXin Li */ divide(CR x)853*a164e4c8SXin Li public CR divide(CR x) { 854*a164e4c8SXin Li return new mult_CR(this, x.inverse()); 855*a164e4c8SXin Li } 856*a164e4c8SXin Li 857*a164e4c8SXin Li /** 858*a164e4c8SXin Li * The real number <TT>x</tt> if <TT>this</tt> < 0, or <TT>y</tt> otherwise. 859*a164e4c8SXin Li * Requires <TT>x</tt> = <TT>y</tt> if <TT>this</tt> = 0. 860*a164e4c8SXin Li * Since comparisons may diverge, this is often 861*a164e4c8SXin Li * a useful alternative to conditionals. 862*a164e4c8SXin Li */ select(CR x, CR y)863*a164e4c8SXin Li public CR select(CR x, CR y) { 864*a164e4c8SXin Li return new select_CR(this, x, y); 865*a164e4c8SXin Li } 866*a164e4c8SXin Li 867*a164e4c8SXin Li /** 868*a164e4c8SXin Li * The maximum of two constructive reals. 869*a164e4c8SXin Li */ max(CR x)870*a164e4c8SXin Li public CR max(CR x) { 871*a164e4c8SXin Li return subtract(x).select(x, this); 872*a164e4c8SXin Li } 873*a164e4c8SXin Li 874*a164e4c8SXin Li /** 875*a164e4c8SXin Li * The minimum of two constructive reals. 876*a164e4c8SXin Li */ min(CR x)877*a164e4c8SXin Li public CR min(CR x) { 878*a164e4c8SXin Li return subtract(x).select(this, x); 879*a164e4c8SXin Li } 880*a164e4c8SXin Li 881*a164e4c8SXin Li /** 882*a164e4c8SXin Li * The absolute value of a constructive reals. 883*a164e4c8SXin Li * Note that this cannot be written as a conditional. 884*a164e4c8SXin Li */ abs()885*a164e4c8SXin Li public CR abs() { 886*a164e4c8SXin Li return select(negate(), this); 887*a164e4c8SXin Li } 888*a164e4c8SXin Li 889*a164e4c8SXin Li /** 890*a164e4c8SXin Li * The exponential function, that is e**<TT>this</tt>. 891*a164e4c8SXin Li */ exp()892*a164e4c8SXin Li public CR exp() { 893*a164e4c8SXin Li final int low_prec = -10; 894*a164e4c8SXin Li BigInteger rough_appr = get_appr(low_prec); 895*a164e4c8SXin Li // Handle negative arguments directly; negating and computing inverse 896*a164e4c8SXin Li // can be very expensive. 897*a164e4c8SXin Li if (rough_appr.compareTo(big2) > 0 || rough_appr.compareTo(bigm2) < 0) { 898*a164e4c8SXin Li CR square_root = shiftRight(1).exp(); 899*a164e4c8SXin Li return square_root.multiply(square_root); 900*a164e4c8SXin Li } else { 901*a164e4c8SXin Li return new prescaled_exp_CR(this); 902*a164e4c8SXin Li } 903*a164e4c8SXin Li } 904*a164e4c8SXin Li 905*a164e4c8SXin Li /** 906*a164e4c8SXin Li * The ratio of a circle's circumference to its diameter. 907*a164e4c8SXin Li */ 908*a164e4c8SXin Li public static CR PI = new gl_pi_CR(); 909*a164e4c8SXin Li 910*a164e4c8SXin Li // Our old PI implementation. Keep this around for now to allow checking. 911*a164e4c8SXin Li // This implementation may also be faster for BigInteger implementations 912*a164e4c8SXin Li // that support only quadratic multiplication, but exhibit high performance 913*a164e4c8SXin Li // for small computations. (The standard Android 6 implementation supports 914*a164e4c8SXin Li // subquadratic multiplication, but has high constant overhead.) Many other 915*a164e4c8SXin Li // atan-based formulas are possible, but based on superficial 916*a164e4c8SXin Li // experimentation, this is roughly as good as the more complex formulas. 917*a164e4c8SXin Li public static CR atan_PI = four.multiply(four.multiply(atan_reciprocal(5)) 918*a164e4c8SXin Li .subtract(atan_reciprocal(239))); 919*a164e4c8SXin Li // pi/4 = 4*atan(1/5) - atan(1/239) 920*a164e4c8SXin Li static CR half_pi = PI.shiftRight(1); 921*a164e4c8SXin Li 922*a164e4c8SXin Li /** 923*a164e4c8SXin Li * The trigonometric cosine function. 924*a164e4c8SXin Li */ cos()925*a164e4c8SXin Li public CR cos() { 926*a164e4c8SXin Li BigInteger halfpi_multiples = divide(PI).get_appr(-1); 927*a164e4c8SXin Li BigInteger abs_halfpi_multiples = halfpi_multiples.abs(); 928*a164e4c8SXin Li if (abs_halfpi_multiples.compareTo(big2) >= 0) { 929*a164e4c8SXin Li // Subtract multiples of PI 930*a164e4c8SXin Li BigInteger pi_multiples = scale(halfpi_multiples, -1); 931*a164e4c8SXin Li CR adjustment = PI.multiply(CR.valueOf(pi_multiples)); 932*a164e4c8SXin Li if (pi_multiples.and(big1).signum() != 0) { 933*a164e4c8SXin Li return subtract(adjustment).cos().negate(); 934*a164e4c8SXin Li } else { 935*a164e4c8SXin Li return subtract(adjustment).cos(); 936*a164e4c8SXin Li } 937*a164e4c8SXin Li } else if (get_appr(-1).abs().compareTo(big2) >= 0) { 938*a164e4c8SXin Li // Scale further with double angle formula 939*a164e4c8SXin Li CR cos_half = shiftRight(1).cos(); 940*a164e4c8SXin Li return cos_half.multiply(cos_half).shiftLeft(1).subtract(ONE); 941*a164e4c8SXin Li } else { 942*a164e4c8SXin Li return new prescaled_cos_CR(this); 943*a164e4c8SXin Li } 944*a164e4c8SXin Li } 945*a164e4c8SXin Li 946*a164e4c8SXin Li /** 947*a164e4c8SXin Li * The trigonometric sine function. 948*a164e4c8SXin Li */ sin()949*a164e4c8SXin Li public CR sin() { 950*a164e4c8SXin Li return half_pi.subtract(this).cos(); 951*a164e4c8SXin Li } 952*a164e4c8SXin Li 953*a164e4c8SXin Li /** 954*a164e4c8SXin Li * The trignonometric arc (inverse) sine function. 955*a164e4c8SXin Li */ asin()956*a164e4c8SXin Li public CR asin() { 957*a164e4c8SXin Li BigInteger rough_appr = get_appr(-10); 958*a164e4c8SXin Li if (rough_appr.compareTo(big750) /* 1/sqrt(2) + a bit */ > 0){ 959*a164e4c8SXin Li CR new_arg = ONE.subtract(multiply(this)).sqrt(); 960*a164e4c8SXin Li return new_arg.acos(); 961*a164e4c8SXin Li } else if (rough_appr.compareTo(bigm750) < 0) { 962*a164e4c8SXin Li return negate().asin().negate(); 963*a164e4c8SXin Li } else { 964*a164e4c8SXin Li return new prescaled_asin_CR(this); 965*a164e4c8SXin Li } 966*a164e4c8SXin Li } 967*a164e4c8SXin Li 968*a164e4c8SXin Li /** 969*a164e4c8SXin Li * The trignonometric arc (inverse) cosine function. 970*a164e4c8SXin Li */ acos()971*a164e4c8SXin Li public CR acos() { 972*a164e4c8SXin Li return half_pi.subtract(asin()); 973*a164e4c8SXin Li } 974*a164e4c8SXin Li 975*a164e4c8SXin Li static final BigInteger low_ln_limit = big8; /* sixteenths, i.e. 1/2 */ 976*a164e4c8SXin Li static final BigInteger high_ln_limit = 977*a164e4c8SXin Li BigInteger.valueOf(16 + 8 /* 1.5 */); 978*a164e4c8SXin Li static final BigInteger scaled_4 = 979*a164e4c8SXin Li BigInteger.valueOf(4*16); 980*a164e4c8SXin Li 981*a164e4c8SXin Li /** 982*a164e4c8SXin Li * The natural (base e) logarithm. 983*a164e4c8SXin Li */ ln()984*a164e4c8SXin Li public CR ln() { 985*a164e4c8SXin Li final int low_prec = -4; 986*a164e4c8SXin Li BigInteger rough_appr = get_appr(low_prec); /* In sixteenths */ 987*a164e4c8SXin Li if (rough_appr.compareTo(big0) < 0) { 988*a164e4c8SXin Li throw new ArithmeticException("ln(negative)"); 989*a164e4c8SXin Li } 990*a164e4c8SXin Li if (rough_appr.compareTo(low_ln_limit) <= 0) { 991*a164e4c8SXin Li return inverse().ln().negate(); 992*a164e4c8SXin Li } 993*a164e4c8SXin Li if (rough_appr.compareTo(high_ln_limit) >= 0) { 994*a164e4c8SXin Li if (rough_appr.compareTo(scaled_4) <= 0) { 995*a164e4c8SXin Li CR quarter = sqrt().sqrt().ln(); 996*a164e4c8SXin Li return quarter.shiftLeft(2); 997*a164e4c8SXin Li } else { 998*a164e4c8SXin Li int extra_bits = rough_appr.bitLength() - 3; 999*a164e4c8SXin Li CR scaled_result = shiftRight(extra_bits).ln(); 1000*a164e4c8SXin Li return scaled_result.add(CR.valueOf(extra_bits).multiply(ln2)); 1001*a164e4c8SXin Li } 1002*a164e4c8SXin Li } 1003*a164e4c8SXin Li return simple_ln(); 1004*a164e4c8SXin Li } 1005*a164e4c8SXin Li 1006*a164e4c8SXin Li /** 1007*a164e4c8SXin Li * The square root of a constructive real. 1008*a164e4c8SXin Li */ sqrt()1009*a164e4c8SXin Li public CR sqrt() { 1010*a164e4c8SXin Li return new sqrt_CR(this); 1011*a164e4c8SXin Li } 1012*a164e4c8SXin Li 1013*a164e4c8SXin Li } // end of CR 1014*a164e4c8SXin Li 1015*a164e4c8SXin Li 1016*a164e4c8SXin Li // 1017*a164e4c8SXin Li // A specialization of CR for cases in which approximate() calls 1018*a164e4c8SXin Li // to increase evaluation precision are somewhat expensive. 1019*a164e4c8SXin Li // If we need to (re)evaluate, we speculatively evaluate to slightly 1020*a164e4c8SXin Li // higher precision, miminimizing reevaluations. 1021*a164e4c8SXin Li // Note that this requires any arguments to be evaluated to higher 1022*a164e4c8SXin Li // precision than absolutely necessary. It can thus potentially 1023*a164e4c8SXin Li // result in lots of wasted effort, and should be used judiciously. 1024*a164e4c8SXin Li // This assumes that the order of magnitude of the number is roughly one. 1025*a164e4c8SXin Li // 1026*a164e4c8SXin Li abstract class slow_CR extends CR { 1027*a164e4c8SXin Li static int max_prec = -64; 1028*a164e4c8SXin Li static int prec_incr = 32; get_appr(int precision)1029*a164e4c8SXin Li public synchronized BigInteger get_appr(int precision) { 1030*a164e4c8SXin Li check_prec(precision); 1031*a164e4c8SXin Li if (appr_valid && precision >= min_prec) { 1032*a164e4c8SXin Li return scale(max_appr, min_prec - precision); 1033*a164e4c8SXin Li } else { 1034*a164e4c8SXin Li int eval_prec = (precision >= max_prec? max_prec : 1035*a164e4c8SXin Li (precision - prec_incr + 1) & ~(prec_incr - 1)); 1036*a164e4c8SXin Li BigInteger result = approximate(eval_prec); 1037*a164e4c8SXin Li min_prec = eval_prec; 1038*a164e4c8SXin Li max_appr = result; 1039*a164e4c8SXin Li appr_valid = true; 1040*a164e4c8SXin Li return scale(result, eval_prec - precision); 1041*a164e4c8SXin Li } 1042*a164e4c8SXin Li } 1043*a164e4c8SXin Li } 1044*a164e4c8SXin Li 1045*a164e4c8SXin Li 1046*a164e4c8SXin Li // Representation of an integer constant. Private. 1047*a164e4c8SXin Li class int_CR extends CR { 1048*a164e4c8SXin Li BigInteger value; int_CR(BigInteger n)1049*a164e4c8SXin Li int_CR(BigInteger n) { 1050*a164e4c8SXin Li value = n; 1051*a164e4c8SXin Li } approximate(int p)1052*a164e4c8SXin Li protected BigInteger approximate(int p) { 1053*a164e4c8SXin Li return scale(value, -p) ; 1054*a164e4c8SXin Li } 1055*a164e4c8SXin Li } 1056*a164e4c8SXin Li 1057*a164e4c8SXin Li // Representation of a number that may not have been completely 1058*a164e4c8SXin Li // evaluated, but is assumed to be an integer. Hence we never 1059*a164e4c8SXin Li // evaluate beyond the decimal point. 1060*a164e4c8SXin Li class assumed_int_CR extends CR { 1061*a164e4c8SXin Li CR value; assumed_int_CR(CR x)1062*a164e4c8SXin Li assumed_int_CR(CR x) { 1063*a164e4c8SXin Li value = x; 1064*a164e4c8SXin Li } approximate(int p)1065*a164e4c8SXin Li protected BigInteger approximate(int p) { 1066*a164e4c8SXin Li if (p >= 0) { 1067*a164e4c8SXin Li return value.get_appr(p); 1068*a164e4c8SXin Li } else { 1069*a164e4c8SXin Li return scale(value.get_appr(0), -p) ; 1070*a164e4c8SXin Li } 1071*a164e4c8SXin Li } 1072*a164e4c8SXin Li } 1073*a164e4c8SXin Li 1074*a164e4c8SXin Li // Representation of the sum of 2 constructive reals. Private. 1075*a164e4c8SXin Li class add_CR extends CR { 1076*a164e4c8SXin Li CR op1; 1077*a164e4c8SXin Li CR op2; add_CR(CR x, CR y)1078*a164e4c8SXin Li add_CR(CR x, CR y) { 1079*a164e4c8SXin Li op1 = x; 1080*a164e4c8SXin Li op2 = y; 1081*a164e4c8SXin Li } approximate(int p)1082*a164e4c8SXin Li protected BigInteger approximate(int p) { 1083*a164e4c8SXin Li // Args need to be evaluated so that each error is < 1/4 ulp. 1084*a164e4c8SXin Li // Rounding error from the cale call is <= 1/2 ulp, so that 1085*a164e4c8SXin Li // final error is < 1 ulp. 1086*a164e4c8SXin Li return scale(op1.get_appr(p-2).add(op2.get_appr(p-2)), -2); 1087*a164e4c8SXin Li } 1088*a164e4c8SXin Li } 1089*a164e4c8SXin Li 1090*a164e4c8SXin Li // Representation of a CR multiplied by 2**n 1091*a164e4c8SXin Li class shifted_CR extends CR { 1092*a164e4c8SXin Li CR op; 1093*a164e4c8SXin Li int count; shifted_CR(CR x, int n)1094*a164e4c8SXin Li shifted_CR(CR x, int n) { 1095*a164e4c8SXin Li op = x; 1096*a164e4c8SXin Li count = n; 1097*a164e4c8SXin Li } approximate(int p)1098*a164e4c8SXin Li protected BigInteger approximate(int p) { 1099*a164e4c8SXin Li return op.get_appr(p - count); 1100*a164e4c8SXin Li } 1101*a164e4c8SXin Li } 1102*a164e4c8SXin Li 1103*a164e4c8SXin Li // Representation of the negation of a constructive real. Private. 1104*a164e4c8SXin Li class neg_CR extends CR { 1105*a164e4c8SXin Li CR op; neg_CR(CR x)1106*a164e4c8SXin Li neg_CR(CR x) { 1107*a164e4c8SXin Li op = x; 1108*a164e4c8SXin Li } approximate(int p)1109*a164e4c8SXin Li protected BigInteger approximate(int p) { 1110*a164e4c8SXin Li return op.get_appr(p).negate(); 1111*a164e4c8SXin Li } 1112*a164e4c8SXin Li } 1113*a164e4c8SXin Li 1114*a164e4c8SXin Li // Representation of: 1115*a164e4c8SXin Li // op1 if selector < 0 1116*a164e4c8SXin Li // op2 if selector >= 0 1117*a164e4c8SXin Li // Assumes x = y if s = 0 1118*a164e4c8SXin Li class select_CR extends CR { 1119*a164e4c8SXin Li CR selector; 1120*a164e4c8SXin Li int selector_sign; 1121*a164e4c8SXin Li CR op1; 1122*a164e4c8SXin Li CR op2; select_CR(CR s, CR x, CR y)1123*a164e4c8SXin Li select_CR(CR s, CR x, CR y) { 1124*a164e4c8SXin Li selector = s; 1125*a164e4c8SXin Li selector_sign = selector.get_appr(-20).signum(); 1126*a164e4c8SXin Li op1 = x; 1127*a164e4c8SXin Li op2 = y; 1128*a164e4c8SXin Li } approximate(int p)1129*a164e4c8SXin Li protected BigInteger approximate(int p) { 1130*a164e4c8SXin Li if (selector_sign < 0) return op1.get_appr(p); 1131*a164e4c8SXin Li if (selector_sign > 0) return op2.get_appr(p); 1132*a164e4c8SXin Li BigInteger op1_appr = op1.get_appr(p-1); 1133*a164e4c8SXin Li BigInteger op2_appr = op2.get_appr(p-1); 1134*a164e4c8SXin Li BigInteger diff = op1_appr.subtract(op2_appr).abs(); 1135*a164e4c8SXin Li if (diff.compareTo(big1) <= 0) { 1136*a164e4c8SXin Li // close enough; use either 1137*a164e4c8SXin Li return scale(op1_appr, -1); 1138*a164e4c8SXin Li } 1139*a164e4c8SXin Li // op1 and op2 are different; selector != 0; 1140*a164e4c8SXin Li // safe to get sign of selector. 1141*a164e4c8SXin Li if (selector.signum() < 0) { 1142*a164e4c8SXin Li selector_sign = -1; 1143*a164e4c8SXin Li return scale(op1_appr, -1); 1144*a164e4c8SXin Li } else { 1145*a164e4c8SXin Li selector_sign = 1; 1146*a164e4c8SXin Li return scale(op2_appr, -1); 1147*a164e4c8SXin Li } 1148*a164e4c8SXin Li } 1149*a164e4c8SXin Li } 1150*a164e4c8SXin Li 1151*a164e4c8SXin Li // Representation of the product of 2 constructive reals. Private. 1152*a164e4c8SXin Li class mult_CR extends CR { 1153*a164e4c8SXin Li CR op1; 1154*a164e4c8SXin Li CR op2; mult_CR(CR x, CR y)1155*a164e4c8SXin Li mult_CR(CR x, CR y) { 1156*a164e4c8SXin Li op1 = x; 1157*a164e4c8SXin Li op2 = y; 1158*a164e4c8SXin Li } approximate(int p)1159*a164e4c8SXin Li protected BigInteger approximate(int p) { 1160*a164e4c8SXin Li int half_prec = (p >> 1) - 1; 1161*a164e4c8SXin Li int msd_op1 = op1.msd(half_prec); 1162*a164e4c8SXin Li int msd_op2; 1163*a164e4c8SXin Li 1164*a164e4c8SXin Li if (msd_op1 == Integer.MIN_VALUE) { 1165*a164e4c8SXin Li msd_op2 = op2.msd(half_prec); 1166*a164e4c8SXin Li if (msd_op2 == Integer.MIN_VALUE) { 1167*a164e4c8SXin Li // Product is small enough that zero will do as an 1168*a164e4c8SXin Li // approximation. 1169*a164e4c8SXin Li return big0; 1170*a164e4c8SXin Li } else { 1171*a164e4c8SXin Li // Swap them, so the larger operand (in absolute value) 1172*a164e4c8SXin Li // is first. 1173*a164e4c8SXin Li CR tmp; 1174*a164e4c8SXin Li tmp = op1; 1175*a164e4c8SXin Li op1 = op2; 1176*a164e4c8SXin Li op2 = tmp; 1177*a164e4c8SXin Li msd_op1 = msd_op2; 1178*a164e4c8SXin Li } 1179*a164e4c8SXin Li } 1180*a164e4c8SXin Li // msd_op1 is valid at this point. 1181*a164e4c8SXin Li int prec2 = p - msd_op1 - 3; // Precision needed for op2. 1182*a164e4c8SXin Li // The appr. error is multiplied by at most 1183*a164e4c8SXin Li // 2 ** (msd_op1 + 1) 1184*a164e4c8SXin Li // Thus each approximation contributes 1/4 ulp 1185*a164e4c8SXin Li // to the rounding error, and the final rounding adds 1186*a164e4c8SXin Li // another 1/2 ulp. 1187*a164e4c8SXin Li BigInteger appr2 = op2.get_appr(prec2); 1188*a164e4c8SXin Li if (appr2.signum() == 0) return big0; 1189*a164e4c8SXin Li msd_op2 = op2.known_msd(); 1190*a164e4c8SXin Li int prec1 = p - msd_op2 - 3; // Precision needed for op1. 1191*a164e4c8SXin Li BigInteger appr1 = op1.get_appr(prec1); 1192*a164e4c8SXin Li int scale_digits = prec1 + prec2 - p; 1193*a164e4c8SXin Li return scale(appr1.multiply(appr2), scale_digits); 1194*a164e4c8SXin Li } 1195*a164e4c8SXin Li } 1196*a164e4c8SXin Li 1197*a164e4c8SXin Li // Representation of the multiplicative inverse of a constructive 1198*a164e4c8SXin Li // real. Private. Should use Newton iteration to refine estimates. 1199*a164e4c8SXin Li class inv_CR extends CR { 1200*a164e4c8SXin Li CR op; inv_CR(CR x)1201*a164e4c8SXin Li inv_CR(CR x) { op = x; } approximate(int p)1202*a164e4c8SXin Li protected BigInteger approximate(int p) { 1203*a164e4c8SXin Li int msd = op.msd(); 1204*a164e4c8SXin Li int inv_msd = 1 - msd; 1205*a164e4c8SXin Li int digits_needed = inv_msd - p + 3; 1206*a164e4c8SXin Li // Number of SIGNIFICANT digits needed for 1207*a164e4c8SXin Li // argument, excl. msd position, which may 1208*a164e4c8SXin Li // be fictitious, since msd routine can be 1209*a164e4c8SXin Li // off by 1. Roughly 1 extra digit is 1210*a164e4c8SXin Li // needed since the relative error is the 1211*a164e4c8SXin Li // same in the argument and result, but 1212*a164e4c8SXin Li // this isn't quite the same as the number 1213*a164e4c8SXin Li // of significant digits. Another digit 1214*a164e4c8SXin Li // is needed to compensate for slop in the 1215*a164e4c8SXin Li // calculation. 1216*a164e4c8SXin Li // One further bit is required, since the 1217*a164e4c8SXin Li // final rounding introduces a 0.5 ulp 1218*a164e4c8SXin Li // error. 1219*a164e4c8SXin Li int prec_needed = msd - digits_needed; 1220*a164e4c8SXin Li int log_scale_factor = -p - prec_needed; 1221*a164e4c8SXin Li if (log_scale_factor < 0) return big0; 1222*a164e4c8SXin Li BigInteger dividend = big1.shiftLeft(log_scale_factor); 1223*a164e4c8SXin Li BigInteger scaled_divisor = op.get_appr(prec_needed); 1224*a164e4c8SXin Li BigInteger abs_scaled_divisor = scaled_divisor.abs(); 1225*a164e4c8SXin Li BigInteger adj_dividend = dividend.add( 1226*a164e4c8SXin Li abs_scaled_divisor.shiftRight(1)); 1227*a164e4c8SXin Li // Adjustment so that final result is rounded. 1228*a164e4c8SXin Li BigInteger result = adj_dividend.divide(abs_scaled_divisor); 1229*a164e4c8SXin Li if (scaled_divisor.signum() < 0) { 1230*a164e4c8SXin Li return result.negate(); 1231*a164e4c8SXin Li } else { 1232*a164e4c8SXin Li return result; 1233*a164e4c8SXin Li } 1234*a164e4c8SXin Li } 1235*a164e4c8SXin Li } 1236*a164e4c8SXin Li 1237*a164e4c8SXin Li 1238*a164e4c8SXin Li // Representation of the exponential of a constructive real. Private. 1239*a164e4c8SXin Li // Uses a Taylor series expansion. Assumes |x| < 1/2. 1240*a164e4c8SXin Li // Note: this is known to be a bad algorithm for 1241*a164e4c8SXin Li // floating point. Unfortunately, other alternatives 1242*a164e4c8SXin Li // appear to require precomputed information. 1243*a164e4c8SXin Li class prescaled_exp_CR extends CR { 1244*a164e4c8SXin Li CR op; prescaled_exp_CR(CR x)1245*a164e4c8SXin Li prescaled_exp_CR(CR x) { op = x; } approximate(int p)1246*a164e4c8SXin Li protected BigInteger approximate(int p) { 1247*a164e4c8SXin Li if (p >= 1) return big0; 1248*a164e4c8SXin Li int iterations_needed = -p/2 + 2; // conservative estimate > 0. 1249*a164e4c8SXin Li // Claim: each intermediate term is accurate 1250*a164e4c8SXin Li // to 2*2^calc_precision. 1251*a164e4c8SXin Li // Total rounding error in series computation is 1252*a164e4c8SXin Li // 2*iterations_needed*2^calc_precision, 1253*a164e4c8SXin Li // exclusive of error in op. 1254*a164e4c8SXin Li int calc_precision = p - bound_log2(2*iterations_needed) 1255*a164e4c8SXin Li - 4; // for error in op, truncation. 1256*a164e4c8SXin Li int op_prec = p - 3; 1257*a164e4c8SXin Li BigInteger op_appr = op.get_appr(op_prec); 1258*a164e4c8SXin Li // Error in argument results in error of < 3/8 ulp. 1259*a164e4c8SXin Li // Sum of term eval. rounding error is < 1/16 ulp. 1260*a164e4c8SXin Li // Series truncation error < 1/16 ulp. 1261*a164e4c8SXin Li // Final rounding error is <= 1/2 ulp. 1262*a164e4c8SXin Li // Thus final error is < 1 ulp. 1263*a164e4c8SXin Li BigInteger scaled_1 = big1.shiftLeft(-calc_precision); 1264*a164e4c8SXin Li BigInteger current_term = scaled_1; 1265*a164e4c8SXin Li BigInteger current_sum = scaled_1; 1266*a164e4c8SXin Li int n = 0; 1267*a164e4c8SXin Li BigInteger max_trunc_error = 1268*a164e4c8SXin Li big1.shiftLeft(p - 4 - calc_precision); 1269*a164e4c8SXin Li while (current_term.abs().compareTo(max_trunc_error) >= 0) { 1270*a164e4c8SXin Li if (Thread.interrupted() || please_stop) throw new AbortedException(); 1271*a164e4c8SXin Li n += 1; 1272*a164e4c8SXin Li /* current_term = current_term * op / n */ 1273*a164e4c8SXin Li current_term = scale(current_term.multiply(op_appr), op_prec); 1274*a164e4c8SXin Li current_term = current_term.divide(BigInteger.valueOf(n)); 1275*a164e4c8SXin Li current_sum = current_sum.add(current_term); 1276*a164e4c8SXin Li } 1277*a164e4c8SXin Li return scale(current_sum, calc_precision - p); 1278*a164e4c8SXin Li } 1279*a164e4c8SXin Li } 1280*a164e4c8SXin Li 1281*a164e4c8SXin Li // Representation of the cosine of a constructive real. Private. 1282*a164e4c8SXin Li // Uses a Taylor series expansion. Assumes |x| < 1. 1283*a164e4c8SXin Li class prescaled_cos_CR extends slow_CR { 1284*a164e4c8SXin Li CR op; prescaled_cos_CR(CR x)1285*a164e4c8SXin Li prescaled_cos_CR(CR x) { 1286*a164e4c8SXin Li op = x; 1287*a164e4c8SXin Li } approximate(int p)1288*a164e4c8SXin Li protected BigInteger approximate(int p) { 1289*a164e4c8SXin Li if (p >= 1) return big0; 1290*a164e4c8SXin Li int iterations_needed = -p/2 + 4; // conservative estimate > 0. 1291*a164e4c8SXin Li // Claim: each intermediate term is accurate 1292*a164e4c8SXin Li // to 2*2^calc_precision. 1293*a164e4c8SXin Li // Total rounding error in series computation is 1294*a164e4c8SXin Li // 2*iterations_needed*2^calc_precision, 1295*a164e4c8SXin Li // exclusive of error in op. 1296*a164e4c8SXin Li int calc_precision = p - bound_log2(2*iterations_needed) 1297*a164e4c8SXin Li - 4; // for error in op, truncation. 1298*a164e4c8SXin Li int op_prec = p - 2; 1299*a164e4c8SXin Li BigInteger op_appr = op.get_appr(op_prec); 1300*a164e4c8SXin Li // Error in argument results in error of < 1/4 ulp. 1301*a164e4c8SXin Li // Cumulative arithmetic rounding error is < 1/16 ulp. 1302*a164e4c8SXin Li // Series truncation error < 1/16 ulp. 1303*a164e4c8SXin Li // Final rounding error is <= 1/2 ulp. 1304*a164e4c8SXin Li // Thus final error is < 1 ulp. 1305*a164e4c8SXin Li BigInteger current_term; 1306*a164e4c8SXin Li int n; 1307*a164e4c8SXin Li BigInteger max_trunc_error = 1308*a164e4c8SXin Li big1.shiftLeft(p - 4 - calc_precision); 1309*a164e4c8SXin Li n = 0; 1310*a164e4c8SXin Li current_term = big1.shiftLeft(-calc_precision); 1311*a164e4c8SXin Li BigInteger current_sum = current_term; 1312*a164e4c8SXin Li while (current_term.abs().compareTo(max_trunc_error) >= 0) { 1313*a164e4c8SXin Li if (Thread.interrupted() || please_stop) throw new AbortedException(); 1314*a164e4c8SXin Li n += 2; 1315*a164e4c8SXin Li /* current_term = - current_term * op * op / n * (n - 1) */ 1316*a164e4c8SXin Li current_term = scale(current_term.multiply(op_appr), op_prec); 1317*a164e4c8SXin Li current_term = scale(current_term.multiply(op_appr), op_prec); 1318*a164e4c8SXin Li BigInteger divisor = BigInteger.valueOf(-n) 1319*a164e4c8SXin Li .multiply(BigInteger.valueOf(n-1)); 1320*a164e4c8SXin Li current_term = current_term.divide(divisor); 1321*a164e4c8SXin Li current_sum = current_sum.add(current_term); 1322*a164e4c8SXin Li } 1323*a164e4c8SXin Li return scale(current_sum, calc_precision - p); 1324*a164e4c8SXin Li } 1325*a164e4c8SXin Li } 1326*a164e4c8SXin Li 1327*a164e4c8SXin Li // The constructive real atan(1/n), where n is a small integer 1328*a164e4c8SXin Li // > base. 1329*a164e4c8SXin Li // This gives a simple and moderately fast way to compute PI. 1330*a164e4c8SXin Li class integral_atan_CR extends slow_CR { 1331*a164e4c8SXin Li int op; integral_atan_CR(int x)1332*a164e4c8SXin Li integral_atan_CR(int x) { op = x; } approximate(int p)1333*a164e4c8SXin Li protected BigInteger approximate(int p) { 1334*a164e4c8SXin Li if (p >= 1) return big0; 1335*a164e4c8SXin Li int iterations_needed = -p/2 + 2; // conservative estimate > 0. 1336*a164e4c8SXin Li // Claim: each intermediate term is accurate 1337*a164e4c8SXin Li // to 2*base^calc_precision. 1338*a164e4c8SXin Li // Total rounding error in series computation is 1339*a164e4c8SXin Li // 2*iterations_needed*base^calc_precision, 1340*a164e4c8SXin Li // exclusive of error in op. 1341*a164e4c8SXin Li int calc_precision = p - bound_log2(2*iterations_needed) 1342*a164e4c8SXin Li - 2; // for error in op, truncation. 1343*a164e4c8SXin Li // Error in argument results in error of < 3/8 ulp. 1344*a164e4c8SXin Li // Cumulative arithmetic rounding error is < 1/4 ulp. 1345*a164e4c8SXin Li // Series truncation error < 1/4 ulp. 1346*a164e4c8SXin Li // Final rounding error is <= 1/2 ulp. 1347*a164e4c8SXin Li // Thus final error is < 1 ulp. 1348*a164e4c8SXin Li BigInteger scaled_1 = big1.shiftLeft(-calc_precision); 1349*a164e4c8SXin Li BigInteger big_op = BigInteger.valueOf(op); 1350*a164e4c8SXin Li BigInteger big_op_squared = BigInteger.valueOf(op*op); 1351*a164e4c8SXin Li BigInteger op_inverse = scaled_1.divide(big_op); 1352*a164e4c8SXin Li BigInteger current_power = op_inverse; 1353*a164e4c8SXin Li BigInteger current_term = op_inverse; 1354*a164e4c8SXin Li BigInteger current_sum = op_inverse; 1355*a164e4c8SXin Li int current_sign = 1; 1356*a164e4c8SXin Li int n = 1; 1357*a164e4c8SXin Li BigInteger max_trunc_error = 1358*a164e4c8SXin Li big1.shiftLeft(p - 2 - calc_precision); 1359*a164e4c8SXin Li while (current_term.abs().compareTo(max_trunc_error) >= 0) { 1360*a164e4c8SXin Li if (Thread.interrupted() || please_stop) throw new AbortedException(); 1361*a164e4c8SXin Li n += 2; 1362*a164e4c8SXin Li current_power = current_power.divide(big_op_squared); 1363*a164e4c8SXin Li current_sign = -current_sign; 1364*a164e4c8SXin Li current_term = 1365*a164e4c8SXin Li current_power.divide(BigInteger.valueOf(current_sign*n)); 1366*a164e4c8SXin Li current_sum = current_sum.add(current_term); 1367*a164e4c8SXin Li } 1368*a164e4c8SXin Li return scale(current_sum, calc_precision - p); 1369*a164e4c8SXin Li } 1370*a164e4c8SXin Li } 1371*a164e4c8SXin Li 1372*a164e4c8SXin Li // Representation for ln(1 + op) 1373*a164e4c8SXin Li class prescaled_ln_CR extends slow_CR { 1374*a164e4c8SXin Li CR op; prescaled_ln_CR(CR x)1375*a164e4c8SXin Li prescaled_ln_CR(CR x) { op = x; } 1376*a164e4c8SXin Li // Compute an approximation of ln(1+x) to precision 1377*a164e4c8SXin Li // prec. This assumes |x| < 1/2. 1378*a164e4c8SXin Li // It uses a Taylor series expansion. 1379*a164e4c8SXin Li // Unfortunately there appears to be no way to take 1380*a164e4c8SXin Li // advantage of old information. 1381*a164e4c8SXin Li // Note: this is known to be a bad algorithm for 1382*a164e4c8SXin Li // floating point. Unfortunately, other alternatives 1383*a164e4c8SXin Li // appear to require precomputed tabular information. approximate(int p)1384*a164e4c8SXin Li protected BigInteger approximate(int p) { 1385*a164e4c8SXin Li if (p >= 0) return big0; 1386*a164e4c8SXin Li int iterations_needed = -p; // conservative estimate > 0. 1387*a164e4c8SXin Li // Claim: each intermediate term is accurate 1388*a164e4c8SXin Li // to 2*2^calc_precision. Total error is 1389*a164e4c8SXin Li // 2*iterations_needed*2^calc_precision 1390*a164e4c8SXin Li // exclusive of error in op. 1391*a164e4c8SXin Li int calc_precision = p - bound_log2(2*iterations_needed) 1392*a164e4c8SXin Li - 4; // for error in op, truncation. 1393*a164e4c8SXin Li int op_prec = p - 3; 1394*a164e4c8SXin Li BigInteger op_appr = op.get_appr(op_prec); 1395*a164e4c8SXin Li // Error analysis as for exponential. 1396*a164e4c8SXin Li BigInteger x_nth = scale(op_appr, op_prec - calc_precision); 1397*a164e4c8SXin Li BigInteger current_term = x_nth; // x**n 1398*a164e4c8SXin Li BigInteger current_sum = current_term; 1399*a164e4c8SXin Li int n = 1; 1400*a164e4c8SXin Li int current_sign = 1; // (-1)^(n-1) 1401*a164e4c8SXin Li BigInteger max_trunc_error = 1402*a164e4c8SXin Li big1.shiftLeft(p - 4 - calc_precision); 1403*a164e4c8SXin Li while (current_term.abs().compareTo(max_trunc_error) >= 0) { 1404*a164e4c8SXin Li if (Thread.interrupted() || please_stop) throw new AbortedException(); 1405*a164e4c8SXin Li n += 1; 1406*a164e4c8SXin Li current_sign = -current_sign; 1407*a164e4c8SXin Li x_nth = scale(x_nth.multiply(op_appr), op_prec); 1408*a164e4c8SXin Li current_term = x_nth.divide(BigInteger.valueOf(n * current_sign)); 1409*a164e4c8SXin Li // x**n / (n * (-1)**(n-1)) 1410*a164e4c8SXin Li current_sum = current_sum.add(current_term); 1411*a164e4c8SXin Li } 1412*a164e4c8SXin Li return scale(current_sum, calc_precision - p); 1413*a164e4c8SXin Li } 1414*a164e4c8SXin Li } 1415*a164e4c8SXin Li 1416*a164e4c8SXin Li // Representation of the arcsine of a constructive real. Private. 1417*a164e4c8SXin Li // Uses a Taylor series expansion. Assumes |x| < (1/2)^(1/3). 1418*a164e4c8SXin Li class prescaled_asin_CR extends slow_CR { 1419*a164e4c8SXin Li CR op; prescaled_asin_CR(CR x)1420*a164e4c8SXin Li prescaled_asin_CR(CR x) { 1421*a164e4c8SXin Li op = x; 1422*a164e4c8SXin Li } approximate(int p)1423*a164e4c8SXin Li protected BigInteger approximate(int p) { 1424*a164e4c8SXin Li // The Taylor series is the sum of x^(2n+1) * (2n)!/(4^n n!^2 (2n+1)) 1425*a164e4c8SXin Li // Note that (2n)!/(4^n n!^2) is always less than one. 1426*a164e4c8SXin Li // (The denominator is effectively 2n*2n*(2n-2)*(2n-2)*...*2*2 1427*a164e4c8SXin Li // which is clearly > (2n)!) 1428*a164e4c8SXin Li // Thus all terms are bounded by x^(2n+1). 1429*a164e4c8SXin Li // Unfortunately, there's no easy way to prescale the argument 1430*a164e4c8SXin Li // to less than 1/sqrt(2), and we can only approximate that. 1431*a164e4c8SXin Li // Thus the worst case iteration count is fairly high. 1432*a164e4c8SXin Li // But it doesn't make much difference. 1433*a164e4c8SXin Li if (p >= 2) return big0; // Never bigger than 4. 1434*a164e4c8SXin Li int iterations_needed = -3 * p / 2 + 4; 1435*a164e4c8SXin Li // conservative estimate > 0. 1436*a164e4c8SXin Li // Follows from assumed bound on x and 1437*a164e4c8SXin Li // the fact that only every other Taylor 1438*a164e4c8SXin Li // Series term is present. 1439*a164e4c8SXin Li // Claim: each intermediate term is accurate 1440*a164e4c8SXin Li // to 2*2^calc_precision. 1441*a164e4c8SXin Li // Total rounding error in series computation is 1442*a164e4c8SXin Li // 2*iterations_needed*2^calc_precision, 1443*a164e4c8SXin Li // exclusive of error in op. 1444*a164e4c8SXin Li int calc_precision = p - bound_log2(2*iterations_needed) 1445*a164e4c8SXin Li - 4; // for error in op, truncation. 1446*a164e4c8SXin Li int op_prec = p - 3; // always <= -2 1447*a164e4c8SXin Li BigInteger op_appr = op.get_appr(op_prec); 1448*a164e4c8SXin Li // Error in argument results in error of < 1/4 ulp. 1449*a164e4c8SXin Li // (Derivative is bounded by 2 in the specified range and we use 1450*a164e4c8SXin Li // 3 extra digits.) 1451*a164e4c8SXin Li // Ignoring the argument error, each term has an error of 1452*a164e4c8SXin Li // < 3ulps relative to calc_precision, which is more precise than p. 1453*a164e4c8SXin Li // Cumulative arithmetic rounding error is < 3/16 ulp (relative to p). 1454*a164e4c8SXin Li // Series truncation error < 2/16 ulp. (Each computed term 1455*a164e4c8SXin Li // is at most 2/3 of last one, so some of remaining series < 1456*a164e4c8SXin Li // 3/2 * current term.) 1457*a164e4c8SXin Li // Final rounding error is <= 1/2 ulp. 1458*a164e4c8SXin Li // Thus final error is < 1 ulp (relative to p). 1459*a164e4c8SXin Li BigInteger max_last_term = 1460*a164e4c8SXin Li big1.shiftLeft(p - 4 - calc_precision); 1461*a164e4c8SXin Li int exp = 1; // Current exponent, = 2n+1 in above expression 1462*a164e4c8SXin Li BigInteger current_term = op_appr.shiftLeft(op_prec - calc_precision); 1463*a164e4c8SXin Li BigInteger current_sum = current_term; 1464*a164e4c8SXin Li BigInteger current_factor = current_term; 1465*a164e4c8SXin Li // Current scaled Taylor series term 1466*a164e4c8SXin Li // before division by the exponent. 1467*a164e4c8SXin Li // Accurate to 3 ulp at calc_precision. 1468*a164e4c8SXin Li while (current_term.abs().compareTo(max_last_term) >= 0) { 1469*a164e4c8SXin Li if (Thread.interrupted() || please_stop) throw new AbortedException(); 1470*a164e4c8SXin Li exp += 2; 1471*a164e4c8SXin Li // current_factor = current_factor * op * op * (exp-1) * (exp-2) / 1472*a164e4c8SXin Li // (exp-1) * (exp-1), with the two exp-1 factors cancelling, 1473*a164e4c8SXin Li // giving 1474*a164e4c8SXin Li // current_factor = current_factor * op * op * (exp-2) / (exp-1) 1475*a164e4c8SXin Li // Thus the error any in the previous term is multiplied by 1476*a164e4c8SXin Li // op^2, adding an error of < (1/2)^(2/3) < 2/3 the original 1477*a164e4c8SXin Li // error. 1478*a164e4c8SXin Li current_factor = current_factor.multiply(BigInteger.valueOf(exp - 2)); 1479*a164e4c8SXin Li current_factor = scale(current_factor.multiply(op_appr), op_prec + 2); 1480*a164e4c8SXin Li // Carry 2 extra bits of precision forward; thus 1481*a164e4c8SXin Li // this effectively introduces 1/8 ulp error. 1482*a164e4c8SXin Li current_factor = current_factor.multiply(op_appr); 1483*a164e4c8SXin Li BigInteger divisor = BigInteger.valueOf(exp - 1); 1484*a164e4c8SXin Li current_factor = current_factor.divide(divisor); 1485*a164e4c8SXin Li // Another 1/4 ulp error here. 1486*a164e4c8SXin Li current_factor = scale(current_factor, op_prec - 2); 1487*a164e4c8SXin Li // Remove extra 2 bits. 1/2 ulp rounding error. 1488*a164e4c8SXin Li // Current_factor has original 3 ulp rounding error, which we 1489*a164e4c8SXin Li // reduced by 1, plus < 1 ulp new rounding error. 1490*a164e4c8SXin Li current_term = current_factor.divide(BigInteger.valueOf(exp)); 1491*a164e4c8SXin Li // Contributes 1 ulp error to sum plus at most 3 ulp 1492*a164e4c8SXin Li // from current_factor. 1493*a164e4c8SXin Li current_sum = current_sum.add(current_term); 1494*a164e4c8SXin Li } 1495*a164e4c8SXin Li return scale(current_sum, calc_precision - p); 1496*a164e4c8SXin Li } 1497*a164e4c8SXin Li } 1498*a164e4c8SXin Li 1499*a164e4c8SXin Li 1500*a164e4c8SXin Li class sqrt_CR extends CR { 1501*a164e4c8SXin Li CR op; sqrt_CR(CR x)1502*a164e4c8SXin Li sqrt_CR(CR x) { op = x; } 1503*a164e4c8SXin Li // Explicitly provide an initial approximation. 1504*a164e4c8SXin Li // Useful for arithmetic geometric mean algorithms, where we've previously 1505*a164e4c8SXin Li // computed a very similar square root. sqrt_CR(CR x, int min_p, BigInteger max_a)1506*a164e4c8SXin Li sqrt_CR(CR x, int min_p, BigInteger max_a) { 1507*a164e4c8SXin Li op = x; 1508*a164e4c8SXin Li min_prec = min_p; 1509*a164e4c8SXin Li max_appr = max_a; 1510*a164e4c8SXin Li appr_valid = true; 1511*a164e4c8SXin Li } 1512*a164e4c8SXin Li final int fp_prec = 50; // Conservative estimate of number of 1513*a164e4c8SXin Li // significant bits in double precision 1514*a164e4c8SXin Li // computation. 1515*a164e4c8SXin Li final int fp_op_prec = 60; approximate(int p)1516*a164e4c8SXin Li protected BigInteger approximate(int p) { 1517*a164e4c8SXin Li int max_op_prec_needed = 2*p - 1; 1518*a164e4c8SXin Li int msd = op.iter_msd(max_op_prec_needed); 1519*a164e4c8SXin Li if (msd <= max_op_prec_needed) return big0; 1520*a164e4c8SXin Li int result_msd = msd/2; // +- 1 1521*a164e4c8SXin Li int result_digits = result_msd - p; // +- 2 1522*a164e4c8SXin Li if (result_digits > fp_prec) { 1523*a164e4c8SXin Li // Compute less precise approximation and use a Newton iter. 1524*a164e4c8SXin Li int appr_digits = result_digits/2 + 6; 1525*a164e4c8SXin Li // This should be conservative. Is fewer enough? 1526*a164e4c8SXin Li int appr_prec = result_msd - appr_digits; 1527*a164e4c8SXin Li int prod_prec = 2*appr_prec; 1528*a164e4c8SXin Li // First compute the argument to maximal precision, so we don't end up 1529*a164e4c8SXin Li // reevaluating it incrementally. 1530*a164e4c8SXin Li BigInteger op_appr = op.get_appr(prod_prec); 1531*a164e4c8SXin Li BigInteger last_appr = get_appr(appr_prec); 1532*a164e4c8SXin Li // Compute (last_appr * last_appr + op_appr) / last_appr / 2 1533*a164e4c8SXin Li // while adjusting the scaling to make everything work 1534*a164e4c8SXin Li BigInteger prod_prec_scaled_numerator = 1535*a164e4c8SXin Li last_appr.multiply(last_appr).add(op_appr); 1536*a164e4c8SXin Li BigInteger scaled_numerator = 1537*a164e4c8SXin Li scale(prod_prec_scaled_numerator, appr_prec - p); 1538*a164e4c8SXin Li BigInteger shifted_result = scaled_numerator.divide(last_appr); 1539*a164e4c8SXin Li return shifted_result.add(big1).shiftRight(1); 1540*a164e4c8SXin Li } else { 1541*a164e4c8SXin Li // Use a double precision floating point approximation. 1542*a164e4c8SXin Li // Make sure all precisions are even 1543*a164e4c8SXin Li int op_prec = (msd - fp_op_prec) & ~1; 1544*a164e4c8SXin Li int working_prec = op_prec - fp_op_prec; 1545*a164e4c8SXin Li BigInteger scaled_bi_appr = op.get_appr(op_prec) 1546*a164e4c8SXin Li .shiftLeft(fp_op_prec); 1547*a164e4c8SXin Li double scaled_appr = scaled_bi_appr.doubleValue(); 1548*a164e4c8SXin Li if (scaled_appr < 0.0) 1549*a164e4c8SXin Li throw new ArithmeticException("sqrt(negative)"); 1550*a164e4c8SXin Li double scaled_fp_sqrt = Math.sqrt(scaled_appr); 1551*a164e4c8SXin Li BigInteger scaled_sqrt = BigInteger.valueOf((long)scaled_fp_sqrt); 1552*a164e4c8SXin Li int shift_count = working_prec/2 - p; 1553*a164e4c8SXin Li return shift(scaled_sqrt, shift_count); 1554*a164e4c8SXin Li } 1555*a164e4c8SXin Li } 1556*a164e4c8SXin Li } 1557*a164e4c8SXin Li 1558*a164e4c8SXin Li // The constant PI, computed using the Gauss-Legendre alternating 1559*a164e4c8SXin Li // arithmetic-geometric mean algorithm: 1560*a164e4c8SXin Li // a[0] = 1 1561*a164e4c8SXin Li // b[0] = 1/sqrt(2) 1562*a164e4c8SXin Li // t[0] = 1/4 1563*a164e4c8SXin Li // p[0] = 1 1564*a164e4c8SXin Li // 1565*a164e4c8SXin Li // a[n+1] = (a[n] + b[n])/2 (arithmetic mean, between 0.8 and 1) 1566*a164e4c8SXin Li // b[n+1] = sqrt(a[n] * b[n]) (geometric mean, between 0.7 and 1) 1567*a164e4c8SXin Li // t[n+1] = t[n] - (2^n)(a[n]-a[n+1])^2, (always between 0.2 and 0.25) 1568*a164e4c8SXin Li // 1569*a164e4c8SXin Li // pi is then approximated as (a[n+1]+b[n+1])^2 / 4*t[n+1]. 1570*a164e4c8SXin Li // 1571*a164e4c8SXin Li class gl_pi_CR extends slow_CR { 1572*a164e4c8SXin Li // In addition to the best approximation kept by the CR base class, we keep 1573*a164e4c8SXin Li // the entire sequence b[n], to the extent we've needed it so far. Each 1574*a164e4c8SXin Li // reevaluation leads to slightly different sqrt arguments, but the 1575*a164e4c8SXin Li // previous result can be used to avoid repeating low precision Newton 1576*a164e4c8SXin Li // iterations for the sqrt approximation. 1577*a164e4c8SXin Li ArrayList<Integer> b_prec = new ArrayList<Integer>(); 1578*a164e4c8SXin Li ArrayList<BigInteger> b_val = new ArrayList<BigInteger>(); gl_pi_CR()1579*a164e4c8SXin Li gl_pi_CR() { 1580*a164e4c8SXin Li b_prec.add(null); // Zeroth entry unused. 1581*a164e4c8SXin Li b_val.add(null); 1582*a164e4c8SXin Li } 1583*a164e4c8SXin Li private static BigInteger TOLERANCE = BigInteger.valueOf(4); 1584*a164e4c8SXin Li // sqrt(1/2) 1585*a164e4c8SXin Li private static CR SQRT_HALF = new sqrt_CR(ONE.shiftRight(1)); 1586*a164e4c8SXin Li approximate(int p)1587*a164e4c8SXin Li protected BigInteger approximate(int p) { 1588*a164e4c8SXin Li // Get us back into a consistent state if the last computation 1589*a164e4c8SXin Li // was interrupted after pushing onto b_prec. 1590*a164e4c8SXin Li if (b_prec.size() > b_val.size()) { 1591*a164e4c8SXin Li b_prec.remove(b_prec.size() - 1); 1592*a164e4c8SXin Li } 1593*a164e4c8SXin Li // Rough approximations are easy. 1594*a164e4c8SXin Li if (p >= 0) return scale(BigInteger.valueOf(3), -p); 1595*a164e4c8SXin Li // We need roughly log2(p) iterations. Each iteration should 1596*a164e4c8SXin Li // contribute no more than 2 ulps to the error in the corresponding 1597*a164e4c8SXin Li // term (a[n], b[n], or t[n]). Thus 2log2(n) bits plus a few for the 1598*a164e4c8SXin Li // final calulation and rounding suffice. 1599*a164e4c8SXin Li final int extra_eval_prec = 1600*a164e4c8SXin Li (int)Math.ceil(Math.log(-p) / Math.log(2)) + 10; 1601*a164e4c8SXin Li // All our terms are implicitly scaled by eval_prec. 1602*a164e4c8SXin Li final int eval_prec = p - extra_eval_prec; 1603*a164e4c8SXin Li BigInteger a = BigInteger.ONE.shiftLeft(-eval_prec); 1604*a164e4c8SXin Li BigInteger b = SQRT_HALF.get_appr(eval_prec); 1605*a164e4c8SXin Li BigInteger t = BigInteger.ONE.shiftLeft(-eval_prec - 2); 1606*a164e4c8SXin Li int n = 0; 1607*a164e4c8SXin Li while (a.subtract(b).subtract(TOLERANCE).signum() > 0) { 1608*a164e4c8SXin Li // Current values correspond to n, next_ values to n + 1 1609*a164e4c8SXin Li // b_prec.size() == b_val.size() >= n + 1 1610*a164e4c8SXin Li final BigInteger next_a = a.add(b).shiftRight(1); 1611*a164e4c8SXin Li final BigInteger next_b; 1612*a164e4c8SXin Li final BigInteger a_diff = a.subtract(next_a); 1613*a164e4c8SXin Li final BigInteger b_prod = a.multiply(b).shiftRight(-eval_prec); 1614*a164e4c8SXin Li // We compute square root approximations using a nested 1615*a164e4c8SXin Li // temporary CR computation, to avoid implementing BigInteger 1616*a164e4c8SXin Li // square roots separately. 1617*a164e4c8SXin Li final CR b_prod_as_CR = CR.valueOf(b_prod).shiftRight(-eval_prec); 1618*a164e4c8SXin Li if (b_prec.size() == n + 1) { 1619*a164e4c8SXin Li // Add an n+1st slot. 1620*a164e4c8SXin Li // Take care to make this exception-safe; b_prec and b_val 1621*a164e4c8SXin Li // must remain consistent, even if we are interrupted, or run 1622*a164e4c8SXin Li // out of memory. It's OK to just push on b_prec in that case. 1623*a164e4c8SXin Li final CR next_b_as_CR = b_prod_as_CR.sqrt(); 1624*a164e4c8SXin Li next_b = next_b_as_CR.get_appr(eval_prec); 1625*a164e4c8SXin Li final BigInteger scaled_next_b = scale(next_b, -extra_eval_prec); 1626*a164e4c8SXin Li b_prec.add(p); 1627*a164e4c8SXin Li b_val.add(scaled_next_b); 1628*a164e4c8SXin Li } else { 1629*a164e4c8SXin Li // Reuse previous approximation to reduce sqrt iterations, 1630*a164e4c8SXin Li // hopefully to one. 1631*a164e4c8SXin Li final CR next_b_as_CR = 1632*a164e4c8SXin Li new sqrt_CR(b_prod_as_CR, 1633*a164e4c8SXin Li b_prec.get(n + 1), b_val.get(n + 1)); 1634*a164e4c8SXin Li next_b = next_b_as_CR.get_appr(eval_prec); 1635*a164e4c8SXin Li // We assume that set() doesn't throw for any reason. 1636*a164e4c8SXin Li b_prec.set(n + 1, p); 1637*a164e4c8SXin Li b_val.set(n + 1, scale(next_b, -extra_eval_prec)); 1638*a164e4c8SXin Li } 1639*a164e4c8SXin Li // b_prec.size() == b_val.size() >= n + 2 1640*a164e4c8SXin Li final BigInteger next_t = 1641*a164e4c8SXin Li t.subtract(a_diff.multiply(a_diff) 1642*a164e4c8SXin Li .shiftLeft(n + eval_prec)); // shift dist. usually neg. 1643*a164e4c8SXin Li a = next_a; 1644*a164e4c8SXin Li b = next_b; 1645*a164e4c8SXin Li t = next_t; 1646*a164e4c8SXin Li ++n; 1647*a164e4c8SXin Li } 1648*a164e4c8SXin Li final BigInteger sum = a.add(b); 1649*a164e4c8SXin Li final BigInteger result = sum.multiply(sum).divide(t).shiftRight(2); 1650*a164e4c8SXin Li return scale(result, -extra_eval_prec); 1651*a164e4c8SXin Li } 1652*a164e4c8SXin Li } 1653