1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/* 2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more 3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements. See the NOTICE file distributed with 4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership. 5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0 6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with 7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License. You may obtain a copy of the License at 8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * http://www.apache.org/licenses/LICENSE-2.0 10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software 12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS, 13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and 15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License. 16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.util; 18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** 20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Faster, more accurate, portable alternative to {@link StrictMath}. 21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Additionally implements the following methods not found in StrictMath: 23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #asinh(double)}</li> 25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #acosh(double)}</li> 26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #atanh(double)}</li> 27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul> 28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The following methods are found in StrictMath since 1.6 only 29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #copySign(double, double)}</li> 31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #getExponent(double)}</li> 32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #nextAfter(double,double)}</li> 33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #nextUp(double)}</li> 34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #scalb(double, int)}</li> 35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #copySign(float, float)}</li> 36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #getExponent(float)}</li> 37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #nextAfter(float,double)}</li> 38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #nextUp(float)}</li> 39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>{@link #scalb(float, int)}</li> 40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul> 41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1074294 $ $Date: 2011-02-24 22:18:59 +0100 (jeu. 24 févr. 2011) $ 42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class FastMath { 45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Archimede's constant PI, ratio of circle circumference to diameter. */ 47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static final double PI = 105414357.0 / 33554432.0 + 1.984187159361080883e-9; 48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Napier's constant e, base of the natural logarithm. */ 50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static final double E = 2850325.0 / 1048576.0 + 8.254840070411028747e-8; 51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Exponential evaluated at integer values, 53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * exp(x) = expIntTableA[x + 750] + expIntTableB[x+750]. 54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double EXP_INT_TABLE_A[] = new double[1500]; 56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Exponential evaluated at integer values, 58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * exp(x) = expIntTableA[x + 750] + expIntTableB[x+750] 59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double EXP_INT_TABLE_B[] = new double[1500]; 61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Exponential over the range of 0 - 1 in increments of 2^-10 63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * exp(x/1024) = expFracTableA[x] + expFracTableB[x]. 64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double EXP_FRAC_TABLE_A[] = new double[1025]; 66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Exponential over the range of 0 - 1 in increments of 2^-10 68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * exp(x/1024) = expFracTableA[x] + expFracTableB[x]. 69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double EXP_FRAC_TABLE_B[] = new double[1025]; 71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Factorial table, for Taylor series expansions. */ 73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double FACT[] = new double[20]; 74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Extended precision logarithm table over the range 1 - 2 in increments of 2^-10. */ 76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double LN_MANT[][] = new double[1024][]; 77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** log(2) (high bits). */ 79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double LN_2_A = 0.693147063255310059; 80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** log(2) (low bits). */ 82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double LN_2_B = 1.17304635250823482e-7; 83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Coefficients for slowLog. */ 85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double LN_SPLIT_COEF[][] = { 86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {2.0, 0.0}, 87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.6666666269302368, 3.9736429850260626E-8}, 88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.3999999761581421, 2.3841857910019882E-8}, 89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.2857142686843872, 1.7029898543501842E-8}, 90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.2222222089767456, 1.3245471311735498E-8}, 91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.1818181574344635, 2.4384203044354907E-8}, 92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.1538461446762085, 9.140260083262505E-9}, 93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.13333332538604736, 9.220590270857665E-9}, 94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.11764700710773468, 1.2393345855018391E-8}, 95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.10526403784751892, 8.251545029714408E-9}, 96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.0952233225107193, 1.2675934823758863E-8}, 97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.08713622391223907, 1.1430250008909141E-8}, 98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.07842259109020233, 2.404307984052299E-9}, 99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.08371849358081818, 1.176342548272881E-8}, 100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.030589580535888672, 1.2958646899018938E-9}, 101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.14982303977012634, 1.225743062930824E-8}, 102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond }; 103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Coefficients for log, when input 0.99 < x < 1.01. */ 105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double LN_QUICK_COEF[][] = { 106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {1.0, 5.669184079525E-24}, 107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {-0.25, -0.25}, 108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.3333333134651184, 1.986821492305628E-8}, 109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {-0.25, -6.663542893624021E-14}, 110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.19999998807907104, 1.1921056801463227E-8}, 111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {-0.1666666567325592, -7.800414592973399E-9}, 112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.1428571343421936, 5.650007086920087E-9}, 113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {-0.12502530217170715, -7.44321345601866E-11}, 114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.11113807559013367, 9.219544613762692E-9}, 115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond }; 116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Coefficients for log in the range of 1.0 < x < 1.0 + 2^-10. */ 118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double LN_HI_PREC_COEF[][] = { 119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {1.0, -6.032174644509064E-23}, 120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {-0.25, -0.25}, 121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.3333333134651184, 1.9868161777724352E-8}, 122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {-0.2499999701976776, -2.957007209750105E-8}, 123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {0.19999954104423523, 1.5830993332061267E-10}, 124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond {-0.16624879837036133, -2.6033824355191673E-8} 125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond }; 126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Sine table (high bits). */ 128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double SINE_TABLE_A[] = new double[14]; 129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Sine table (low bits). */ 131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double SINE_TABLE_B[] = new double[14]; 132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Cosine table (high bits). */ 134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double COSINE_TABLE_A[] = new double[14]; 135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Cosine table (low bits). */ 137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double COSINE_TABLE_B[] = new double[14]; 138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Tangent table, used by atan() (high bits). */ 140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double TANGENT_TABLE_A[] = new double[14]; 141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Tangent table, used by atan() (low bits). */ 143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double TANGENT_TABLE_B[] = new double[14]; 144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Bits of 1/(2*pi), need for reducePayneHanek(). */ 146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long RECIP_2PI[] = new long[] { 147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x28be60dbL << 32) | 0x9391054aL, 148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x7f09d5f4L << 32) | 0x7d4d3770L, 149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x36d8a566L << 32) | 0x4f10e410L, 150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x7f9458eaL << 32) | 0xf7aef158L, 151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x6dc91b8eL << 32) | 0x909374b8L, 152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x01924bbaL << 32) | 0x82746487L, 153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x3f877ac7L << 32) | 0x2c4a69cfL, 154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0xba208d7dL << 32) | 0x4baed121L, 155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x3a671c09L << 32) | 0xad17df90L, 156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x4e64758eL << 32) | 0x60d4ce7dL, 157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x272117e2L << 32) | 0xef7e4a0eL, 158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0xc7fe25ffL << 32) | 0xf7816603L, 159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0xfbcbc462L << 32) | 0xd6829b47L, 160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0xdb4d9fb3L << 32) | 0xc9f2c26dL, 161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0xd3d18fd9L << 32) | 0xa797fa8bL, 162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0x5d49eeb1L << 32) | 0xfaf97c5eL, 163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0xcf41ce7dL << 32) | 0xe294a4baL, 164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 0x9afed7ecL << 32 }; 165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Bits of pi/4, need for reducePayneHanek(). */ 167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long PI_O_4_BITS[] = new long[] { 168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0xc90fdaa2L << 32) | 0x2168c234L, 169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (0xc4c6628bL << 32) | 0x80dc1cd1L }; 170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Eighths. 172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This is used by sinQ, because its faster to do a table lookup than 173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * a multiply in this time-critical routine 174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double EIGHTHS[] = {0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.125, 1.25, 1.375, 1.5, 1.625}; 176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Table of 2^((n+2)/3) */ 178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double CBRTTWO[] = { 0.6299605249474366, 179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 0.7937005259840998, 180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1.0, 181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1.2599210498948732, 182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1.5874010519681994 }; 183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * There are 52 bits in the mantissa of a double. 186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For additional precision, the code splits double numbers into two parts, 187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * by clearing the low order 30 bits if possible, and then performs the arithmetic 188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * on each half separately. 189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 0x40000000 - used to split a double into two parts, both with the low order bits cleared. 193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Equivalent to 2^30. 194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long HEX_40000000 = 0x40000000L; // 1073741824L 196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Mask used to clear low order 30 bits */ 198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long MASK_30BITS = -1L - (HEX_40000000 -1); // 0xFFFFFFFFC0000000L; 199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 2^52 - double numbers this large must be integral (no fraction) or NaN or Infinite */ 201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final double TWO_POWER_52 = 4503599627370496.0; 202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Initialize tables 204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond static { 205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int i; 206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Generate an array of factorials 208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond FACT[0] = 1.0; 209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (i = 1; i < FACT.length; i++) { 210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond FACT[i] = FACT[i-1] * i; 211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp[] = new double[2]; 214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double recip[] = new double[2]; 215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Populate expIntTable 217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (i = 0; i < 750; i++) { 218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expint(i, tmp); 219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond EXP_INT_TABLE_A[i+750] = tmp[0]; 220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond EXP_INT_TABLE_B[i+750] = tmp[1]; 221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (i != 0) { 223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Negative integer powers 224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitReciprocal(tmp, recip); 225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond EXP_INT_TABLE_A[750-i] = recip[0]; 226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond EXP_INT_TABLE_B[750-i] = recip[1]; 227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Populate expFracTable 231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (i = 0; i < EXP_FRAC_TABLE_A.length; i++) { 232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond slowexp(i/1024.0, tmp); 233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond EXP_FRAC_TABLE_A[i] = tmp[0]; 234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond EXP_FRAC_TABLE_B[i] = tmp[1]; 235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Populate lnMant table 238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (i = 0; i < LN_MANT.length; i++) { 239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double d = Double.longBitsToDouble( (((long) i) << 42) | 0x3ff0000000000000L ); 240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LN_MANT[i] = slowLog(d); 241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Build the sine and cosine tables 244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond buildSinCosTables(); 245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Private Constructor 249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private FastMath() { 251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Generic helper methods 254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get the high order bits from the mantissa. 257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Equivalent to adding and subtracting HEX_40000 but also works for very large numbers 258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param d the value to split 260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the high order part of the mantissa 261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double doubleHighPart(double d) { 263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (d > -MathUtils.SAFE_MIN && d < MathUtils.SAFE_MIN){ 264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return d; // These are un-normalised - don't try to convert 265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long xl = Double.doubleToLongBits(d); 267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xl = xl & MASK_30BITS; // Drop low order bits 268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.longBitsToDouble(xl); 269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the square root of a number. 272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p><b>Note:</b> this implementation currently delegates to {@link Math#sqrt} 273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a number on which evaluation is done 274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return square root of a 275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double sqrt(final double a) { 277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.sqrt(a); 278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the hyperbolic cosine of a number. 281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number on which evaluation is done 282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return hyperbolic cosine of x 283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double cosh(double x) { 285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x) { 286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 20.0) { 290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return exp(x)/2.0; 291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < -20) { 294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return exp(-x)/2.0; 295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double hiPrec[] = new double[2]; 298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0.0) { 299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x = -x; 300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond exp(x, 0.0, hiPrec); 302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = hiPrec[0] + hiPrec[1]; 304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = -(ya - hiPrec[0] - hiPrec[1]); 305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = ya * HEX_40000000; 307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yaa = ya + temp - temp; 308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yab = ya - yaa; 309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // recip = 1/y 311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double recip = 1.0/ya; 312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = recip * HEX_40000000; 313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double recipa = recip + temp - temp; 314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double recipb = recip - recipa; 315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Correct for rounding in division 317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip; 318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Account for yb 319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond recipb += -yb * recip * recip; 320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // y = y + 1/y 322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + recipa; 323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - recipa); 324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + recipb; 326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - recipb); 327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result = ya + yb; 330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result *= 0.5; 331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the hyperbolic sine of a number. 335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number on which evaluation is done 336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return hyperbolic sine of x 337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double sinh(double x) { 339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean negate = false; 340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x) { 341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 20.0) { 345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return exp(x)/2.0; 346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < -20) { 349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -exp(-x)/2.0; 350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 0) { 353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0.0) { 357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x = -x; 358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negate = true; 359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result; 362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 0.25) { 364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double hiPrec[] = new double[2]; 365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond exp(x, 0.0, hiPrec); 366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = hiPrec[0] + hiPrec[1]; 368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = -(ya - hiPrec[0] - hiPrec[1]); 369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = ya * HEX_40000000; 371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yaa = ya + temp - temp; 372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yab = ya - yaa; 373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // recip = 1/y 375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double recip = 1.0/ya; 376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = recip * HEX_40000000; 377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double recipa = recip + temp - temp; 378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double recipb = recip - recipa; 379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Correct for rounding in division 381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip; 382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Account for yb 383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond recipb += -yb * recip * recip; 384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond recipa = -recipa; 386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond recipb = -recipb; 387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // y = y + 1/y 389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + recipa; 390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - recipa); 391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + recipb; 393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - recipb); 394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = ya + yb; 397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result *= 0.5; 398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond else { 400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double hiPrec[] = new double[2]; 401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expm1(x, hiPrec); 402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = hiPrec[0] + hiPrec[1]; 404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = -(ya - hiPrec[0] - hiPrec[1]); 405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */ 407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double denom = 1.0 + ya; 408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double denomr = 1.0 / denom; 409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double denomb = -(denom - 1.0 - ya) + yb; 410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ratio = ya * denomr; 411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = ratio * HEX_40000000; 412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ra = ratio + temp - temp; 413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double rb = ratio - ra; 414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = denom * HEX_40000000; 416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double za = denom + temp - temp; 417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double zb = denom - za; 418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += (ya - za*ra - za*rb - zb*ra - zb*rb) * denomr; 420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Adjust for yb 422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += yb*denomr; // numerator 423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += -ya * denomb * denomr * denomr; // denominator 424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // y = y - 1/y 426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + ra; 427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - ra); 428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + rb; 430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - rb); 431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = ya + yb; 434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result *= 0.5; 435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (negate) { 438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = -result; 439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the hyperbolic tangent of a number. 445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number on which evaluation is done 446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return hyperbolic tangent of x 447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double tanh(double x) { 449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean negate = false; 450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x) { 452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 20.0) { 456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 1.0; 457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < -20) { 460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -1.0; 461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 0) { 464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0.0) { 468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x = -x; 469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negate = true; 470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result; 473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x >= 0.5) { 474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double hiPrec[] = new double[2]; 475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // tanh(x) = (exp(2x) - 1) / (exp(2x) + 1) 476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond exp(x*2.0, 0.0, hiPrec); 477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = hiPrec[0] + hiPrec[1]; 479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = -(ya - hiPrec[0] - hiPrec[1]); 480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Numerator */ 482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double na = -1.0 + ya; 483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double nb = -(na + 1.0 - ya); 484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = na + yb; 485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond nb += -(temp - na - yb); 486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond na = temp; 487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Denominator */ 489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double da = 1.0 + ya; 490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double db = -(da - 1.0 - ya); 491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = da + yb; 492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond db += -(temp - da - yb); 493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond da = temp; 494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = da * HEX_40000000; 496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double daa = da + temp - temp; 497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double dab = da - daa; 498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // ratio = na/da 500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ratio = na/da; 501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ratio * HEX_40000000; 502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ratioa = ratio + temp - temp; 503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ratiob = ratio - ratioa; 504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Correct for rounding in division 506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da; 507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Account for nb 509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ratiob += nb / da; 510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Account for db 511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ratiob += -db * na / da / da; 512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = ratioa + ratiob; 514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond else { 516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double hiPrec[] = new double[2]; 517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // tanh(x) = expm1(2x) / (expm1(2x) + 2) 518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expm1(x*2.0, hiPrec); 519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 520dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = hiPrec[0] + hiPrec[1]; 521dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = -(ya - hiPrec[0] - hiPrec[1]); 522dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 523dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Numerator */ 524dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double na = ya; 525dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double nb = yb; 526dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 527dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Denominator */ 528dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double da = 2.0 + ya; 529dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double db = -(da - 2.0 - ya); 530dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = da + yb; 531dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond db += -(temp - da - yb); 532dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond da = temp; 533dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 534dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = da * HEX_40000000; 535dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double daa = da + temp - temp; 536dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double dab = da - daa; 537dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 538dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // ratio = na/da 539dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ratio = na/da; 540dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ratio * HEX_40000000; 541dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ratioa = ratio + temp - temp; 542dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ratiob = ratio - ratioa; 543dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 544dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Correct for rounding in division 545dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da; 546dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 547dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Account for nb 548dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ratiob += nb / da; 549dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Account for db 550dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ratiob += -db * na / da / da; 551dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 552dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = ratioa + ratiob; 553dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 554dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 555dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (negate) { 556dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = -result; 557dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 558dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 559dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 560dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 561dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 562dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the inverse hyperbolic cosine of a number. 563dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a number on which evaluation is done 564dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return inverse hyperbolic cosine of a 565dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 566dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double acosh(final double a) { 567dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return FastMath.log(a + FastMath.sqrt(a * a - 1)); 568dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 569dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 570dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the inverse hyperbolic sine of a number. 571dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a number on which evaluation is done 572dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return inverse hyperbolic sine of a 573dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 574dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double asinh(double a) { 575dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 576dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean negative = false; 577dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a < 0) { 578dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negative = true; 579dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = -a; 580dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 581dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 582dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double absAsinh; 583dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a > 0.167) { 584dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAsinh = FastMath.log(FastMath.sqrt(a * a + 1) + a); 585dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 586dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double a2 = a * a; 587dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a > 0.097) { 588dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0 - a2 * (1.0 / 11.0 - a2 * (1.0 / 13.0 - a2 * (1.0 / 15.0 - a2 * (1.0 / 17.0) * 15.0 / 16.0) * 13.0 / 14.0) * 11.0 / 12.0) * 9.0 / 10.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0); 589dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (a > 0.036) { 590dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0 - a2 * (1.0 / 11.0 - a2 * (1.0 / 13.0) * 11.0 / 12.0) * 9.0 / 10.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0); 591dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (a > 0.0036) { 592dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0); 593dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 594dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0) * 3.0 / 4.0) / 2.0); 595dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 596dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 597dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 598dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return negative ? -absAsinh : absAsinh; 599dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 600dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 601dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 602dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the inverse hyperbolic tangent of a number. 603dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a number on which evaluation is done 604dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return inverse hyperbolic tangent of a 605dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 606dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double atanh(double a) { 607dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 608dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean negative = false; 609dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a < 0) { 610dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negative = true; 611dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = -a; 612dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 613dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 614dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double absAtanh; 615dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a > 0.15) { 616dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAtanh = 0.5 * FastMath.log((1 + a) / (1 - a)); 617dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 618dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double a2 = a * a; 619dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a > 0.087) { 620dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0 + a2 * (1.0 / 11.0 + a2 * (1.0 / 13.0 + a2 * (1.0 / 15.0 + a2 * (1.0 / 17.0))))))))); 621dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (a > 0.031) { 622dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0 + a2 * (1.0 / 11.0 + a2 * (1.0 / 13.0))))))); 623dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (a > 0.003) { 624dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0))))); 625dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 626dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0))); 627dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 628dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 629dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 630dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return negative ? -absAtanh : absAtanh; 631dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 632dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 633dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 634dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the signum of a number. 635dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise 636dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a number on which evaluation is done 637dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a 638dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 639dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double signum(final double a) { 640dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (a < 0.0) ? -1.0 : ((a > 0.0) ? 1.0 : a); // return +0.0/-0.0/NaN depending on a 641dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 642dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 643dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the signum of a number. 644dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise 645dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a number on which evaluation is done 646dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a 647dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 648dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float signum(final float a) { 649dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (a < 0.0f) ? -1.0f : ((a > 0.0f) ? 1.0f : a); // return +0.0/-0.0/NaN depending on a 650dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 651dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 652dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute next number towards positive infinity. 653dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a number to which neighbor should be computed 654dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return neighbor of a towards positive infinity 655dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 656dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double nextUp(final double a) { 657dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return nextAfter(a, Double.POSITIVE_INFINITY); 658dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 659dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 660dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute next number towards positive infinity. 661dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a number to which neighbor should be computed 662dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return neighbor of a towards positive infinity 663dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 664dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float nextUp(final float a) { 665dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return nextAfter(a, Float.POSITIVE_INFINITY); 666dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 667dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 668dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Returns a pseudo-random number between 0.0 and 1.0. 669dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p><b>Note:</b> this implementation currently delegates to {@link Math#random} 670dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a random number between 0.0 and 1.0 671dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 672dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double random() { 673dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.random(); 674dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 675dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 676dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 677dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Exponential function. 678dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 679dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Computes exp(x), function result is nearly rounded. It will be correctly 680dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * rounded to the theoretical value for 99.9% of input values, otherwise it will 681dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * have a 1 UPL error. 682dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 683dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Method: 684dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Lookup intVal = exp(int(x)) 685dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Lookup fracVal = exp(int(x-int(x) / 1024.0) * 1024.0 ); 686dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Compute z as the exponential of the remaining bits by a polynomial minus one 687dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * exp(x) = intVal * fracVal * (1 + z) 688dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 689dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Accuracy: 690dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Calculation is done with 63 bits of precision, so result should be correctly 691dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * rounded for 99.9% of input values, with less than 1 ULP error otherwise. 692dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 693dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a double 694dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return double e<sup>x</sup> 695dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 696dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double exp(double x) { 697dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return exp(x, 0.0, null); 698dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 699dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 700dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 701dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Internal helper method for exponential function. 702dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x original argument of the exponential function 703dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param extra extra bits of precision on input (To Be Confirmed) 704dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param hiPrec extra bits of precision on output (To Be Confirmed) 705dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return exp(x) 706dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 707dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double exp(double x, double extra, double[] hiPrec) { 708dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double intPartA; 709dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double intPartB; 710dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int intVal; 711dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 712dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Lookup exp(floor(x)). 713dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * intPartA will have the upper 22 bits, intPartB will have the lower 714dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 52 bits. 715dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 716dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0.0) { 717dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond intVal = (int) -x; 718dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 719dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (intVal > 746) { 720dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 721dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] = 0.0; 722dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[1] = 0.0; 723dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 724dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 725dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 726dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 727dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (intVal > 709) { 728dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* This will produce a subnormal output */ 729dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double result = exp(x+40.19140625, extra, hiPrec) / 285040095144011776.0; 730dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 731dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] /= 285040095144011776.0; 732dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[1] /= 285040095144011776.0; 733dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 734dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 735dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 736dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 737dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (intVal == 709) { 738dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* exp(1.494140625) is nearly a machine number... */ 739dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double result = exp(x+1.494140625, extra, hiPrec) / 4.455505956692756620; 740dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 741dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] /= 4.455505956692756620; 742dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[1] /= 4.455505956692756620; 743dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 744dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 745dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 746dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 747dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond intVal++; 748dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 749dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond intPartA = EXP_INT_TABLE_A[750-intVal]; 750dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond intPartB = EXP_INT_TABLE_B[750-intVal]; 751dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 752dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond intVal = -intVal; 753dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 754dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond intVal = (int) x; 755dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 756dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (intVal > 709) { 757dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 758dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] = Double.POSITIVE_INFINITY; 759dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[1] = 0.0; 760dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 761dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 762dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 763dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 764dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond intPartA = EXP_INT_TABLE_A[750+intVal]; 765dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond intPartB = EXP_INT_TABLE_B[750+intVal]; 766dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 767dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 768dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Get the fractional part of x, find the greatest multiple of 2^-10 less than 769dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * x and look up the exp function of it. 770dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * fracPartA will have the upper 22 bits, fracPartB the lower 52 bits. 771dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 772dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int intFrac = (int) ((x - intVal) * 1024.0); 773dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double fracPartA = EXP_FRAC_TABLE_A[intFrac]; 774dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double fracPartB = EXP_FRAC_TABLE_B[intFrac]; 775dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 776dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* epsilon is the difference in x from the nearest multiple of 2^-10. It 777dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * has a value in the range 0 <= epsilon < 2^-10. 778dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Do the subtraction from x as the last step to avoid possible loss of percison. 779dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 780dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double epsilon = x - (intVal + intFrac / 1024.0); 781dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 782dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute z = exp(epsilon) - 1.0 via a minimax polynomial. z has 783dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond full double precision (52 bits). Since z < 2^-10, we will have 784dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 62 bits of precision when combined with the contant 1. This will be 785dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond used in the last addition below to get proper rounding. */ 786dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 787dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Remez generated polynomial. Converges on the interval [0, 2^-10], error 788dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond is less than 0.5 ULP */ 789dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double z = 0.04168701738764507; 790dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * epsilon + 0.1666666505023083; 791dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * epsilon + 0.5000000000042687; 792dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * epsilon + 1.0; 793dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * epsilon + -3.940510424527919E-20; 794dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 795dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute (intPartA+intPartB) * (fracPartA+fracPartB) by binomial 796dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expansion. 797dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tempA is exact since intPartA and intPartB only have 22 bits each. 798dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tempB will have 52 bits of precision. 799dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 800dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tempA = intPartA * fracPartA; 801dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tempB = intPartA * fracPartB + intPartB * fracPartA + intPartB * fracPartB; 802dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 803dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute the result. (1+z)(tempA+tempB). Order of operations is 804dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond important. For accuracy add by increasing size. tempA is exact and 805dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond much larger than the others. If there are extra bits specified from the 806dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pow() function, use them. */ 807dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double tempC = tempB + tempA; 808dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double result; 809dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (extra != 0.0) { 810dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = tempC*extra*z + tempC*extra + tempC*z + tempB + tempA; 811dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 812dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = tempC*z + tempB + tempA; 813dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 814dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 815dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 816dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // If requesting high precision 817dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] = tempA; 818dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[1] = tempC*extra*z + tempC*extra + tempC*z + tempB; 819dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 820dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 821dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 822dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 823dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 824dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute exp(x) - 1 825dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number to compute shifted exponential 826dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return exp(x) - 1 827dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 828dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double expm1(double x) { 829dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return expm1(x, null); 830dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 831dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 832dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Internal helper method for expm1 833dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number to compute shifted exponential 834dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param hiPrecOut receive high precision result for -1.0 < x < 1.0 835dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return exp(x) - 1 836dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 837dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double expm1(double x, double hiPrecOut[]) { 838dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x || x == 0.0) { // NaN or zero 839dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 840dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 841dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 842dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x <= -1.0 || x >= 1.0) { 843dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // If not between +/- 1.0 844dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //return exp(x) - 1.0; 845dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double hiPrec[] = new double[2]; 846dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond exp(x, 0.0, hiPrec); 847dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 0.0) { 848dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -1.0 + hiPrec[0] + hiPrec[1]; 849dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 850dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double ra = -1.0 + hiPrec[0]; 851dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double rb = -(ra + 1.0 - hiPrec[0]); 852dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += hiPrec[1]; 853dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ra + rb; 854dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 855dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 856dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 857dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double baseA; 858dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double baseB; 859dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double epsilon; 860dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean negative = false; 861dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 862dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0.0) { 863dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x = -x; 864dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negative = true; 865dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 866dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 867dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond { 868dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int intFrac = (int) (x * 1024.0); 869dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tempA = EXP_FRAC_TABLE_A[intFrac] - 1.0; 870dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tempB = EXP_FRAC_TABLE_B[intFrac]; 871dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 872dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = tempA + tempB; 873dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tempB = -(temp - tempA - tempB); 874dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tempA = temp; 875dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 876dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = tempA * HEX_40000000; 877dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond baseA = tempA + temp - temp; 878dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond baseB = tempB + (tempA - baseA); 879dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 880dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond epsilon = x - intFrac/1024.0; 881dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 882dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 883dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 884dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute expm1(epsilon) */ 885dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double zb = 0.008336750013465571; 886dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = zb * epsilon + 0.041666663879186654; 887dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = zb * epsilon + 0.16666666666745392; 888dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = zb * epsilon + 0.49999999999999994; 889dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = zb * epsilon; 890dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = zb * epsilon; 891dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 892dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double za = epsilon; 893dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = za + zb; 894dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = -(temp - za - zb); 895dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = temp; 896dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 897dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = za * HEX_40000000; 898dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = za + temp - temp; 899dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb += za - temp; 900dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = temp; 901dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 902dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Combine the parts. expm1(a+b) = expm1(a) + expm1(b) + expm1(a)*expm1(b) */ 903dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = za * baseA; 904dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //double yb = za*baseB + zb*baseA + zb*baseB; 905dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + za * baseB; 906dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = -(temp - ya - za * baseB); 907dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 908dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 909dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + zb * baseA; 910dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - zb * baseA); 911dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 912dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 913dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + zb * baseB; 914dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - zb*baseB); 915dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 916dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 917dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //ya = ya + za + baseA; 918dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //yb = yb + zb + baseB; 919dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + baseA; 920dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - baseA - ya); 921dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 922dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 923dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + za; 924dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //yb += (ya > za) ? -(temp - ya - za) : -(temp - za - ya); 925dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - za); 926dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 927dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 928dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + baseB; 929dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //yb += (ya > baseB) ? -(temp - ya - baseB) : -(temp - baseB - ya); 930dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - baseB); 931dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 932dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 933dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + zb; 934dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //yb += (ya > zb) ? -(temp - ya - zb) : -(temp - zb - ya); 935dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -(temp - ya - zb); 936dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 937dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 938dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (negative) { 939dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */ 940dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double denom = 1.0 + ya; 941dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double denomr = 1.0 / denom; 942dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double denomb = -(denom - 1.0 - ya) + yb; 943dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ratio = ya * denomr; 944dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ratio * HEX_40000000; 945dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double ra = ratio + temp - temp; 946dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double rb = ratio - ra; 947dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 948dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = denom * HEX_40000000; 949dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = denom + temp - temp; 950dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = denom - za; 951dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 952dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += (ya - za * ra - za * rb - zb * ra - zb * rb) * denomr; 953dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 954dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // f(x) = x/1+x 955dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute f'(x) 956dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Product rule: d(uv) = du*v + u*dv 957dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Chain rule: d(f(g(x)) = f'(g(x))*f(g'(x)) 958dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // d(1/x) = -1/(x*x) 959dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // d(1/1+x) = -1/( (1+x)^2) * 1 = -1/((1+x)*(1+x)) 960dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // d(x/1+x) = -x/((1+x)(1+x)) + 1/1+x = 1 / ((1+x)(1+x)) 961dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 962dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Adjust for yb 963dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += yb * denomr; // numerator 964dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += -ya * denomb * denomr * denomr; // denominator 965dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 966dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // negate 967dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = -ra; 968dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = -rb; 969dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 970dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 971dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrecOut != null) { 972dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrecOut[0] = ya; 973dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrecOut[1] = yb; 974dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 975dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 976dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ya + yb; 977dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 978dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 979dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 980dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For x between 0 and 1, returns exp(x), uses extended precision 981dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x argument of exponential 982dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param result placeholder where to place exp(x) split in two terms 983dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * for extra precision (i.e. exp(x) = result[0] ° result[1] 984dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return exp(x) 985dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 986dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double slowexp(final double x, final double result[]) { 987dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xs[] = new double[2]; 988dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double ys[] = new double[2]; 989dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double facts[] = new double[2]; 990dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double as[] = new double[2]; 991dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(x, xs); 992dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = ys[1] = 0.0; 993dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 994dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 19; i >= 0; i--) { 995dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, as); 996dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = as[0]; 997dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[1] = as[1]; 998dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 999dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(FACT[i], as); 1000dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitReciprocal(as, facts); 1001dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1002dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitAdd(ys, facts, as); 1003dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = as[0]; 1004dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[1] = as[1]; 1005dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1006dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1007dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (result != null) { 1008dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = ys[0]; 1009dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = ys[1]; 1010dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1011dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1012dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ys[0] + ys[1]; 1013dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1014dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1015dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute split[0], split[1] such that their sum is equal to d, 1016dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * and split[0] has its 30 least significant bits as zero. 1017dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param d number to split 1018dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param split placeholder where to place the result 1019dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1020dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static void split(final double d, final double split[]) { 1021dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (d < 8e298 && d > -8e298) { 1022dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double a = d * HEX_40000000; 1023dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split[0] = (d + a) - a; 1024dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split[1] = d - split[0]; 1025dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1026dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double a = d * 9.31322574615478515625E-10; 1027dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split[0] = (d + a - d) * HEX_40000000; 1028dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split[1] = d - split[0]; 1029dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1030dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1031dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1032dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Recompute a split. 1033dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a input/out array containing the split, changed 1034dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * on output 1035dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1036dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static void resplit(final double a[]) { 1037dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double c = a[0] + a[1]; 1038dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double d = -(c - a[0] - a[1]); 1039dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1040dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (c < 8e298 && c > -8e298) { 1041dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double z = c * HEX_40000000; 1042dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a[0] = (c + z) - z; 1043dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a[1] = c - a[0] + d; 1044dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1045dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double z = c * 9.31322574615478515625E-10; 1046dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a[0] = (c + z - c) * HEX_40000000; 1047dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a[1] = c - a[0] + d; 1048dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1049dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1050dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1051dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Multiply two numbers in split form. 1052dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first term of multiplication 1053dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second term of multiplication 1054dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param ans placeholder where to put the result 1055dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1056dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static void splitMult(double a[], double b[], double ans[]) { 1057dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ans[0] = a[0] * b[0]; 1058dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ans[1] = a[0] * b[1] + a[1] * b[0] + a[1] * b[1]; 1059dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1060dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Resplit */ 1061dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond resplit(ans); 1062dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1063dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1064dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Add two numbers in split form. 1065dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first term of addition 1066dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second term of addition 1067dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param ans placeholder where to put the result 1068dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1069dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static void splitAdd(final double a[], final double b[], final double ans[]) { 1070dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ans[0] = a[0] + b[0]; 1071dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ans[1] = a[1] + b[1]; 1072dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1073dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond resplit(ans); 1074dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1075dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1076dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the reciprocal of in. Use the following algorithm. 1077dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * in = c + d. 1078dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * want to find x + y such that x+y = 1/(c+d) and x is much 1079dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * larger than y and x has several zero bits on the right. 1080dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1081dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Set b = 1/(2^22), a = 1 - b. Thus (a+b) = 1. 1082dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Use following identity to compute (a+b)/(c+d) 1083dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1084dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (a+b)/(c+d) = a/c + (bc - ad) / (c^2 + cd) 1085dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * set x = a/c and y = (bc - ad) / (c^2 + cd) 1086dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This will be close to the right answer, but there will be 1087dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * some rounding in the calculation of X. So by carefully 1088dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * computing 1 - (c+d)(x+y) we can compute an error and 1089dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * add that back in. This is done carefully so that terms 1090dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of similar size are subtracted first. 1091dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param in initial number, in split form 1092dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param result placeholder where to put the result 1093dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1094dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static void splitReciprocal(final double in[], final double result[]) { 1095dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double b = 1.0/4194304.0; 1096dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double a = 1.0 - b; 1097dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1098dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (in[0] == 0.0) { 1099dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond in[0] = in[1]; 1100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond in[1] = 0.0; 1101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = a / in[0]; 1104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = (b*in[0]-a*in[1]) / (in[0]*in[0] + in[0]*in[1]); 1105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (result[1] != result[1]) { // can happen if result[1] is NAN 1107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = 0.0; 1108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Resplit */ 1111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond resplit(result); 1112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < 2; i++) { 1114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* this may be overkill, probably once is enough */ 1115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double err = 1.0 - result[0] * in[0] - result[0] * in[1] - 1116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] * in[0] - result[1] * in[1]; 1117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /*err = 1.0 - err; */ 1118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond err = err * (result[0] + result[1]); 1119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /*printf("err = %16e\n", err); */ 1120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] += err; 1121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute (a[0] + a[1]) * (b[0] + b[1]) in extended precision. 1125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first term of the multiplication 1126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second term of the multiplication 1127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param result placeholder where to put the result 1128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static void quadMult(final double a[], final double b[], final double result[]) { 1130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xs[] = new double[2]; 1131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double ys[] = new double[2]; 1132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double zs[] = new double[2]; 1133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* a[0] * b[0] */ 1135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(a[0], xs); 1136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(b[0], ys); 1137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, zs); 1138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = zs[0]; 1140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = zs[1]; 1141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* a[0] * b[1] */ 1143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(b[1], ys); 1144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, zs); 1145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp = result[0] + zs[0]; 1147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = result[1] - (tmp - result[0] - zs[0]); 1148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = tmp; 1149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = result[0] + zs[1]; 1150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = result[1] - (tmp - result[0] - zs[1]); 1151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = tmp; 1152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* a[1] * b[0] */ 1154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(a[1], xs); 1155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(b[0], ys); 1156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, zs); 1157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = result[0] + zs[0]; 1159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = result[1] - (tmp - result[0] - zs[0]); 1160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = tmp; 1161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = result[0] + zs[1]; 1162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = result[1] - (tmp - result[0] - zs[1]); 1163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = tmp; 1164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* a[1] * b[0] */ 1166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(a[1], xs); 1167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(b[1], ys); 1168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, zs); 1169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = result[0] + zs[0]; 1171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = result[1] - (tmp - result[0] - zs[0]); 1172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = tmp; 1173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = result[0] + zs[1]; 1174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = result[1] - (tmp - result[0] - zs[1]); 1175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = tmp; 1176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute exp(p) for a integer p in extended precision. 1179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p integer whose exponential is requested 1180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param result placeholder where to put the result in extended precision 1181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return exp(p) in standard precision (equal to result[0] + result[1]) 1182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double expint(int p, final double result[]) { 1184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //double x = M_E; 1185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xs[] = new double[2]; 1186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double as[] = new double[2]; 1187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double ys[] = new double[2]; 1188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //split(x, xs); 1189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //xs[1] = (double)(2.7182818284590452353602874713526625L - xs[0]); 1190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //xs[0] = 2.71827697753906250000; 1191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //xs[1] = 4.85091998273542816811e-06; 1192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //xs[0] = Double.longBitsToDouble(0x4005bf0800000000L); 1193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //xs[1] = Double.longBitsToDouble(0x3ed458a2bb4a9b00L); 1194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* E */ 1196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[0] = 2.718281828459045; 1197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[1] = 1.4456468917292502E-16; 1198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(1.0, ys); 1200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while (p > 0) { 1202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((p & 1) != 0) { 1203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadMult(ys, xs, as); 1204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = as[0]; ys[1] = as[1]; 1205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadMult(xs, xs, as); 1208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[0] = as[0]; xs[1] = as[1]; 1209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p >>= 1; 1211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (result != null) { 1214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = ys[0]; 1215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = ys[1]; 1216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond resplit(result); 1218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ys[0] + ys[1]; 1221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 1225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Natural logarithm. 1226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a double 1228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return log(x) 1229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double log(final double x) { 1231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return log(x, null); 1232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 1235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Internal helper method for natural logarithm function. 1236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x original argument of the natural logarithm function 1237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param hiPrec extra bits of precision on output (To Be Confirmed) 1238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return log(x) 1239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double log(final double x, final double[] hiPrec) { 1241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x==0) { // Handle special case of +0/-0 1242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NEGATIVE_INFINITY; 1243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long bits = Double.doubleToLongBits(x); 1245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Handle special cases of negative input, and NaN */ 1247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((bits & 0x8000000000000000L) != 0 || x != x) { 1248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != 0.0) { 1249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 1250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] = Double.NaN; 1251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 1254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Handle special cases of Positive infinity. */ 1258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.POSITIVE_INFINITY) { 1259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 1260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] = Double.POSITIVE_INFINITY; 1261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 1264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Extract the exponent */ 1267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int exp = (int)(bits >> 52)-1023; 1268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((bits & 0x7ff0000000000000L) == 0) { 1270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Subnormal! 1271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 0) { 1272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Zero 1273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 1274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] = Double.NEGATIVE_INFINITY; 1275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NEGATIVE_INFINITY; 1278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Normalize the subnormal number. */ 1281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bits <<= 1; 1282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while ( (bits & 0x0010000000000000L) == 0) { 1283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond exp--; 1284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bits <<= 1; 1285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (exp == -1 || exp == 0) { 1290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 1.01 && x > 0.99 && hiPrec == null) { 1291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* The normal method doesn't work well in the range [0.99, 1.01], so call do a straight 1292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond polynomial expansion in higer precision. */ 1293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute x - 1.0 and split it */ 1295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xa = x - 1.0; 1296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xb = xa - x + 1.0; 1297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp = xa * HEX_40000000; 1298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double aa = xa + tmp - tmp; 1299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ab = xa - aa; 1300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = aa; 1301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = ab; 1302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = LN_QUICK_COEF[LN_QUICK_COEF.length-1][0]; 1304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = LN_QUICK_COEF[LN_QUICK_COEF.length-1][1]; 1305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = LN_QUICK_COEF.length - 2; i >= 0; i--) { 1307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply a = y * x */ 1308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond aa = ya * xa; 1309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ab = ya * xb + yb * xa + yb * xb; 1310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* split, so now y = a */ 1311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = aa * HEX_40000000; 1312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = aa + tmp - tmp; 1313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = aa - ya + ab; 1314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Add a = y + lnQuickCoef */ 1316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond aa = ya + LN_QUICK_COEF[i][0]; 1317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ab = yb + LN_QUICK_COEF[i][1]; 1318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Split y = a */ 1319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = aa * HEX_40000000; 1320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = aa + tmp - tmp; 1321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = aa - ya + ab; 1322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply a = y * x */ 1325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond aa = ya * xa; 1326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ab = ya * xb + yb * xa + yb * xb; 1327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* split, so now y = a */ 1328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = aa * HEX_40000000; 1329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = aa + tmp - tmp; 1330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = aa - ya + ab; 1331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ya + yb; 1333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // lnm is a log of a number in the range of 1.0 - 2.0, so 0 <= lnm < ln(2) 1337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double lnm[] = LN_MANT[(int)((bits & 0x000ffc0000000000L) >> 42)]; 1338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 1340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double epsilon = x / Double.longBitsToDouble(bits & 0xfffffc0000000000L); 1341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond epsilon -= 1.0; 1343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // y is the most significant 10 bits of the mantissa 1346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //double y = Double.longBitsToDouble(bits & 0xfffffc0000000000L); 1347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //double epsilon = (x - y) / y; 1348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double epsilon = (bits & 0x3ffffffffffL) / (TWO_POWER_52 + (bits & 0x000ffc0000000000L)); 1349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double lnza = 0.0; 1351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double lnzb = 0.0; 1352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 1354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* split epsilon -> x */ 1355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp = epsilon * HEX_40000000; 1356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double aa = epsilon + tmp - tmp; 1357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ab = epsilon - aa; 1358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xa = aa; 1359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xb = ab; 1360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Need a more accurate epsilon, so adjust the division. */ 1362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double numer = bits & 0x3ffffffffffL; 1363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double denom = TWO_POWER_52 + (bits & 0x000ffc0000000000L); 1364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond aa = numer - xa*denom - xb * denom; 1365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb += aa / denom; 1366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Remez polynomial evaluation */ 1368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = LN_HI_PREC_COEF[LN_HI_PREC_COEF.length-1][0]; 1369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = LN_HI_PREC_COEF[LN_HI_PREC_COEF.length-1][1]; 1370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = LN_HI_PREC_COEF.length - 2; i >= 0; i--) { 1372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply a = y * x */ 1373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond aa = ya * xa; 1374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ab = ya * xb + yb * xa + yb * xb; 1375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* split, so now y = a */ 1376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = aa * HEX_40000000; 1377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = aa + tmp - tmp; 1378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = aa - ya + ab; 1379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Add a = y + lnHiPrecCoef */ 1381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond aa = ya + LN_HI_PREC_COEF[i][0]; 1382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ab = yb + LN_HI_PREC_COEF[i][1]; 1383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Split y = a */ 1384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = aa * HEX_40000000; 1385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = aa + tmp - tmp; 1386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = aa - ya + ab; 1387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply a = y * x */ 1390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond aa = ya * xa; 1391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ab = ya * xb + yb * xa + yb * xb; 1392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* split, so now lnz = a */ 1394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 1395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = aa * 1073741824.0; 1396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = aa + tmp - tmp; 1397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnzb = aa - lnza + ab; 1398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = aa + ab; 1400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnzb = -(lnza - aa - ab); 1401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* High precision not required. Eval Remez polynomial 1403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond using standard double precision */ 1404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = -0.16624882440418567; 1405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = lnza * epsilon + 0.19999954120254515; 1406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = lnza * epsilon + -0.2499999997677497; 1407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = lnza * epsilon + 0.3333333333332802; 1408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = lnza * epsilon + -0.5; 1409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = lnza * epsilon + 1.0; 1410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnza = lnza * epsilon; 1411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Relative sizes: 1414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * lnzb [0, 2.33E-10] 1415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * lnm[1] [0, 1.17E-7] 1416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * ln2B*exp [0, 1.12E-4] 1417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * lnza [0, 9.7E-4] 1418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * lnm[0] [0, 0.692] 1419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * ln2A*exp [0, 709] 1420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute the following sum: 1423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * lnzb + lnm[1] + ln2B*exp + lnza + lnm[0] + ln2A*exp; 1424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //return lnzb + lnm[1] + ln2B*exp + lnza + lnm[0] + ln2A*exp; 1427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double a = LN_2_A*exp; 1428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double b = 0.0; 1429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double c = a+lnm[0]; 1430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double d = -(c-a-lnm[0]); 1431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 1432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 1433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + lnza; 1435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - lnza); 1436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 1437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 1438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + LN_2_B*exp; 1440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - LN_2_B*exp); 1441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 1442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 1443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + lnm[1]; 1445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - lnm[1]); 1446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 1447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 1448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + lnzb; 1450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - lnzb); 1451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 1452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 1453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (hiPrec != null) { 1455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[0] = a; 1456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hiPrec[1] = b; 1457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a + b; 1460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute log(1 + x). 1463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a number 1464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return log(1 + x) 1465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double log1p(final double x) { 1467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xpa = 1.0 + x; 1468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xpb = -(xpa - 1.0 - x); 1469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == -1) { 1471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x/0.0; // -Infinity 1472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 0 && 1/x == 0) { // x = Infinity 1475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 1476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x>1e-6 || x<-1e-6) { 1479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double hiPrec[] = new double[2]; 1480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double lores = log(xpa, hiPrec); 1482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN 1483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return lores; 1484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Do a taylor series expansion around xpa */ 1487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* f(x+y) = f(x) + f'(x)*y + f''(x)/2 y^2 */ 1488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double fx1 = xpb/xpa; 1489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double epsilon = 0.5 * fx1 + 1.0; 1491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond epsilon = epsilon * fx1; 1492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return epsilon + hiPrec[1] + hiPrec[0]; 1494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Value is small |x| < 1e6, do a Taylor series centered on 1.0 */ 1497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double y = x * 0.333333333333333 - 0.5; 1498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y = y * x + 1.0; 1499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y = y * x; 1500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; 1502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the base 10 logarithm. 1505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a number 1506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return log10(x) 1507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double log10(final double x) { 1509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double hiPrec[] = new double[2]; 1510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double lores = log(x, hiPrec); 1512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN 1513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return lores; 1514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double tmp = hiPrec[0] * HEX_40000000; 1517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double lna = hiPrec[0] + tmp - tmp; 1518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double lnb = hiPrec[0] - lna + hiPrec[1]; 1519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1520dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double rln10a = 0.4342944622039795; 1521dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double rln10b = 1.9699272335463627E-8; 1522dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1523dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return rln10b * lnb + rln10b * lna + rln10a * lnb + rln10a * lna; 1524dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1525dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1526dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 1527dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Power function. Compute x^y. 1528dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1529dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a double 1530dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param y a double 1531dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return double 1532dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1533dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double pow(double x, double y) { 1534dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double lns[] = new double[2]; 1535dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1536dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == 0.0) { 1537dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 1.0; 1538dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1539dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1540dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x) { // X is NaN 1541dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 1542dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1543dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1544dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1545dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 0) { 1546dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long bits = Double.doubleToLongBits(x); 1547dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((bits & 0x8000000000000000L) != 0) { 1548dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // -zero 1549dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long yi = (long) y; 1550dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1551dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0 && y == yi && (yi & 1) == 1) { 1552dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NEGATIVE_INFINITY; 1553dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1554dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1555dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0 && y == yi && (yi & 1) == 1) { 1556dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -0.0; 1557dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1558dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1559dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y > 0 && y == yi && (yi & 1) == 1) { 1560dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -0.0; 1561dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1562dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1563dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1564dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0) { 1565dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 1566dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1567dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y > 0) { 1568dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 1569dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1570dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1571dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 1572dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1573dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1574dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.POSITIVE_INFINITY) { 1575dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y != y) { // y is NaN 1576dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; 1577dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1578dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0.0) { 1579dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 1580dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1581dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 1582dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1583dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1584dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1585dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == Double.POSITIVE_INFINITY) { 1586dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x * x == 1.0) 1587dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 1588dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1589dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x * x > 1.0) { 1590dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 1591dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1592dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 1593dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1594dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1595dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1596dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.NEGATIVE_INFINITY) { 1597dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y != y) { // y is NaN 1598dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; 1599dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1600dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1601dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0) { 1602dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long yi = (long) y; 1603dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == yi && (yi & 1) == 1) { 1604dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -0.0; 1605dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1606dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1607dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 1608dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1609dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1610dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y > 0) { 1611dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long yi = (long) y; 1612dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == yi && (yi & 1) == 1) { 1613dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NEGATIVE_INFINITY; 1614dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1615dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1616dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 1617dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1618dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1619dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1620dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == Double.NEGATIVE_INFINITY) { 1621dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1622dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x * x == 1.0) { 1623dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 1624dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1625dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1626dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x * x < 1.0) { 1627dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 1628dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1629dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 1630dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1631dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1632dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1633dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Handle special case x<0 */ 1634dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0) { 1635dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // y is an even integer in this case 1636dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y >= TWO_POWER_52 || y <= -TWO_POWER_52) { 1637dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return pow(-x, y); 1638dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1639dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1640dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == (long) y) { 1641dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // If y is an integer 1642dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ((long)y & 1) == 0 ? pow(-x, y) : -pow(-x, y); 1643dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1644dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 1645dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1646dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1647dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1648dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Split y into ya and yb such that y = ya+yb */ 1649dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya; 1650dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb; 1651dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 8e298 && y > -8e298) { 1652dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp1 = y * HEX_40000000; 1653dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = y + tmp1 - tmp1; 1654dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = y - ya; 1655dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1656dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp1 = y * 9.31322574615478515625E-10; 1657dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp2 = tmp1 * 9.31322574615478515625E-10; 1658dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = (tmp1 + tmp2 - tmp1) * HEX_40000000 * HEX_40000000; 1659dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = y - ya; 1660dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1661dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1662dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute ln(x) */ 1663dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double lores = log(x, lns); 1664dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN 1665dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return lores; 1666dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1667dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1668dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double lna = lns[0]; 1669dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double lnb = lns[1]; 1670dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1671dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* resplit lns */ 1672dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp1 = lna * HEX_40000000; 1673dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp2 = lna + tmp1 - tmp1; 1674dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnb += lna - tmp2; 1675dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lna = tmp2; 1676dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1677dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // y*ln(x) = (aa+ab) 1678dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double aa = lna * ya; 1679dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double ab = lna * yb + lnb * ya + lnb * yb; 1680dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1681dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lna = aa+ab; 1682dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lnb = -(lna - aa - ab); 1683dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1684dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double z = 1.0 / 120.0; 1685dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * lnb + (1.0 / 24.0); 1686dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * lnb + (1.0 / 6.0); 1687dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * lnb + 0.5; 1688dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * lnb + 1.0; 1689dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond z = z * lnb; 1690dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1691dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double result = exp(lna, z, null); 1692dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //result = result + result * z; 1693dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 1694dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1695dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1696dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** xi in the range of [1, 2]. 1697dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 3 5 7 1698dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * x+1 / x x x \ 1699dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * ln ----- = 2 * | x + ---- + ---- + ---- + ... | 1700dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1-x \ 3 5 7 / 1701dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1702dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * So, compute a Remez approximation of the following function 1703dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1704dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * ln ((sqrt(x)+1)/(1-sqrt(x))) / x 1705dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1706dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This will be an even function with only positive coefficents. 1707dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * x is in the range [0 - 1/3]. 1708dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1709dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Transform xi for input to the above function by setting 1710dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * x = (xi-1)/(xi+1). Input to the polynomial is x^2, then 1711dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the result is multiplied by x. 1712dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xi number from which log is requested 1713dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return log(xi) 1714dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1715dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double[] slowLog(double xi) { 1716dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double x[] = new double[2]; 1717dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double x2[] = new double[2]; 1718dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double y[] = new double[2]; 1719dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double a[] = new double[2]; 1720dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1721dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(xi, x); 1722dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1723dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Set X = (x-1)/(x+1) */ 1724dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x[0] += 1.0; 1725dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond resplit(x); 1726dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitReciprocal(x, a); 1727dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x[0] -= 2.0; 1728dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond resplit(x); 1729dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(x, a, y); 1730dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x[0] = y[0]; 1731dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x[1] = y[1]; 1732dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1733dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Square X -> X2*/ 1734dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(x, x, x2); 1735dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1736dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1737dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //x[0] -= 1.0; 1738dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //resplit(x); 1739dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1740dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y[0] = LN_SPLIT_COEF[LN_SPLIT_COEF.length-1][0]; 1741dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y[1] = LN_SPLIT_COEF[LN_SPLIT_COEF.length-1][1]; 1742dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1743dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = LN_SPLIT_COEF.length-2; i >= 0; i--) { 1744dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(y, x2, a); 1745dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y[0] = a[0]; 1746dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y[1] = a[1]; 1747dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitAdd(y, LN_SPLIT_COEF[i], a); 1748dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y[0] = a[0]; 1749dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y[1] = a[1]; 1750dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1751dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1752dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(y, x, a); 1753dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y[0] = a[0]; 1754dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y[1] = a[1]; 1755dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1756dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; 1757dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1758dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1759dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 1760dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For x between 0 and pi/4 compute sine. 1761dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which sine is requested 1762dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param result placeholder where to put the result in extended precision 1763dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return sin(x) 1764dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1765dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double slowSin(final double x, final double result[]) { 1766dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xs[] = new double[2]; 1767dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double ys[] = new double[2]; 1768dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double facts[] = new double[2]; 1769dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double as[] = new double[2]; 1770dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(x, xs); 1771dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = ys[1] = 0.0; 1772dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1773dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 19; i >= 0; i--) { 1774dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, as); 1775dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = as[0]; ys[1] = as[1]; 1776dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1777dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (i & 1) == 0) { 1778dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond continue; 1779dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1780dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1781dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(FACT[i], as); 1782dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitReciprocal(as, facts); 1783dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1784dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (i & 2) != 0 ) { 1785dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond facts[0] = -facts[0]; 1786dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond facts[1] = -facts[1]; 1787dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1788dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1789dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitAdd(ys, facts, as); 1790dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = as[0]; ys[1] = as[1]; 1791dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1792dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1793dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (result != null) { 1794dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = ys[0]; 1795dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = ys[1]; 1796dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1797dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1798dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ys[0] + ys[1]; 1799dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1800dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1801dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 1802dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For x between 0 and pi/4 compute cosine 1803dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which cosine is requested 1804dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param result placeholder where to put the result in extended precision 1805dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return cos(x) 1806dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1807dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double slowCos(final double x, final double result[]) { 1808dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1809dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xs[] = new double[2]; 1810dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double ys[] = new double[2]; 1811dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double facts[] = new double[2]; 1812dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double as[] = new double[2]; 1813dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(x, xs); 1814dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = ys[1] = 0.0; 1815dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1816dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 19; i >= 0; i--) { 1817dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, as); 1818dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = as[0]; ys[1] = as[1]; 1819dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1820dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (i & 1) != 0) { 1821dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond continue; 1822dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1823dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1824dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond split(FACT[i], as); 1825dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitReciprocal(as, facts); 1826dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1827dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (i & 2) != 0 ) { 1828dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond facts[0] = -facts[0]; 1829dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond facts[1] = -facts[1]; 1830dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1831dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1832dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitAdd(ys, facts, as); 1833dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = as[0]; ys[1] = as[1]; 1834dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1835dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1836dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (result != null) { 1837dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = ys[0]; 1838dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = ys[1]; 1839dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1840dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1841dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ys[0] + ys[1]; 1842dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1843dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1844dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Build the sine and cosine tables. 1845dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1846dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static void buildSinCosTables() { 1847dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double result[] = new double[2]; 1848dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1849dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Use taylor series for 0 <= x <= 6/8 */ 1850dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < 7; i++) { 1851dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double x = i / 8.0; 1852dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1853dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond slowSin(x, result); 1854dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond SINE_TABLE_A[i] = result[0]; 1855dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond SINE_TABLE_B[i] = result[1]; 1856dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1857dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond slowCos(x, result); 1858dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond COSINE_TABLE_A[i] = result[0]; 1859dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond COSINE_TABLE_B[i] = result[1]; 1860dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1861dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1862dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Use angle addition formula to complete table to 13/8, just beyond pi/2 */ 1863dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 7; i < 14; i++) { 1864dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xs[] = new double[2]; 1865dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ys[] = new double[2]; 1866dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double as[] = new double[2]; 1867dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double bs[] = new double[2]; 1868dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temps[] = new double[2]; 1869dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1870dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (i & 1) == 0) { 1871dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Even, use double angle 1872dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[0] = SINE_TABLE_A[i/2]; 1873dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[1] = SINE_TABLE_B[i/2]; 1874dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = COSINE_TABLE_A[i/2]; 1875dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[1] = COSINE_TABLE_B[i/2]; 1876dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1877dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* compute sine */ 1878dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, result); 1879dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond SINE_TABLE_A[i] = result[0] * 2.0; 1880dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond SINE_TABLE_B[i] = result[1] * 2.0; 1881dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1882dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute cosine */ 1883dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(ys, ys, as); 1884dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, xs, temps); 1885dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temps[0] = -temps[0]; 1886dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temps[1] = -temps[1]; 1887dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitAdd(as, temps, result); 1888dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond COSINE_TABLE_A[i] = result[0]; 1889dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond COSINE_TABLE_B[i] = result[1]; 1890dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 1891dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[0] = SINE_TABLE_A[i/2]; 1892dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[1] = SINE_TABLE_B[i/2]; 1893dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[0] = COSINE_TABLE_A[i/2]; 1894dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ys[1] = COSINE_TABLE_B[i/2]; 1895dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond as[0] = SINE_TABLE_A[i/2+1]; 1896dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond as[1] = SINE_TABLE_B[i/2+1]; 1897dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bs[0] = COSINE_TABLE_A[i/2+1]; 1898dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bs[1] = COSINE_TABLE_B[i/2+1]; 1899dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1900dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* compute sine */ 1901dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, bs, temps); 1902dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(ys, as, result); 1903dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitAdd(result, temps, result); 1904dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond SINE_TABLE_A[i] = result[0]; 1905dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond SINE_TABLE_B[i] = result[1]; 1906dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1907dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute cosine */ 1908dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(ys, bs, result); 1909dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, as, temps); 1910dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temps[0] = -temps[0]; 1911dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temps[1] = -temps[1]; 1912dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitAdd(result, temps, result); 1913dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond COSINE_TABLE_A[i] = result[0]; 1914dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond COSINE_TABLE_B[i] = result[1]; 1915dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1916dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1917dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1918dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute tangent = sine/cosine */ 1919dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < 14; i++) { 1920dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xs[] = new double[2]; 1921dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ys[] = new double[2]; 1922dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double as[] = new double[2]; 1923dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1924dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond as[0] = COSINE_TABLE_A[i]; 1925dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond as[1] = COSINE_TABLE_B[i]; 1926dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1927dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitReciprocal(as, ys); 1928dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1929dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[0] = SINE_TABLE_A[i]; 1930dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xs[1] = SINE_TABLE_B[i]; 1931dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1932dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond splitMult(xs, ys, as); 1933dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1934dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond TANGENT_TABLE_A[i] = as[0]; 1935dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond TANGENT_TABLE_B[i] = as[1]; 1936dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1937dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1938dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1939dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1940dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 1941dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Computes sin(x) - x, where |x| < 1/16. 1942dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Use a Remez polynomial approximation. 1943dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a number smaller than 1/16 1944dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return sin(x) - x 1945dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1946dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double polySine(final double x) 1947dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond { 1948dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double x2 = x*x; 1949dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1950dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double p = 2.7553817452272217E-6; 1951dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p = p * x2 + -1.9841269659586505E-4; 1952dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p = p * x2 + 0.008333333333329196; 1953dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p = p * x2 + -0.16666666666666666; 1954dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //p *= x2; 1955dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //p *= x; 1956dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p = p * x2 * x; 1957dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1958dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return p; 1959dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1960dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1961dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 1962dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Computes cos(x) - 1, where |x| < 1/16. 1963dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Use a Remez polynomial approximation. 1964dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a number smaller than 1/16 1965dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return cos(x) - 1 1966dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1967dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double polyCosine(double x) { 1968dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double x2 = x*x; 1969dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1970dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double p = 2.479773539153719E-5; 1971dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p = p * x2 + -0.0013888888689039883; 1972dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p = p * x2 + 0.041666666666621166; 1973dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p = p * x2 + -0.49999999999999994; 1974dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p *= x2; 1975dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1976dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return p; 1977dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 1978dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1979dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 1980dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Compute sine over the first quadrant (0 < x < pi/2). 1981dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Use combination of table lookup and rational polynomial expansion. 1982dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xa number from which sine is requested 1983dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xb extra bits for x (may be 0.0) 1984dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return sin(xa + xb) 1985dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 1986dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double sinQ(double xa, double xb) { 1987dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int idx = (int) ((xa * 8.0) + 0.5); 1988dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double epsilon = xa - EIGHTHS[idx]; //idx*0.125; 1989dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1990dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Table lookups 1991dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double sintA = SINE_TABLE_A[idx]; 1992dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double sintB = SINE_TABLE_B[idx]; 1993dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double costA = COSINE_TABLE_A[idx]; 1994dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double costB = COSINE_TABLE_B[idx]; 1995dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 1996dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Polynomial eval of sin(epsilon), cos(epsilon) 1997dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double sinEpsA = epsilon; 1998dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double sinEpsB = polySine(epsilon); 1999dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double cosEpsA = 1.0; 2000dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double cosEpsB = polyCosine(epsilon); 2001dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2002dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Split epsilon xa + xb = x 2003dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double temp = sinEpsA * HEX_40000000; 2004dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp2 = (sinEpsA + temp) - temp; 2005dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond sinEpsB += sinEpsA - temp2; 2006dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond sinEpsA = temp2; 2007dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2008dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute sin(x) by angle addition formula */ 2009dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result; 2010dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2011dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute the following sum: 2012dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2013dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB + 2014dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; 2015dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2016dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Ranges of elements 2017dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2018dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * xxxtA 0 PI/2 2019dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * xxxtB -1.5e-9 1.5e-9 2020dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sinEpsA -0.0625 0.0625 2021dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sinEpsB -6e-11 6e-11 2022dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * cosEpsA 1.0 2023dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * cosEpsB 0 -0.0625 2024dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2025dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2026dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2027dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB + 2028dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; 2029dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2030dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //result = sintA + sintA*cosEpsB + sintB + sintB * cosEpsB; 2031dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //result += costA*sinEpsA + costA*sinEpsB + costB*sinEpsA + costB * sinEpsB; 2032dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double a = 0; 2033dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double b = 0; 2034dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2035dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double t = sintA; 2036dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double c = a + t; 2037dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double d = -(c - a - t); 2038dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2039dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2040dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2041dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = costA * sinEpsA; 2042dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2043dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2044dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2045dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2046dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2047dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + sintA * cosEpsB + costA * sinEpsB; 2048dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 2049dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = sintA*cosEpsB; 2050dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2051dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2052dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2053dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2054dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2055dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = costA*sinEpsB; 2056dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2057dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2058dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2059dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2060dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2061dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2062dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + sintB + costB * sinEpsA + sintB * cosEpsB + costB * sinEpsB; 2063dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 2064dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = sintB; 2065dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2066dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2067dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2068dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2069dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2070dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = costB*sinEpsA; 2071dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2072dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2073dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2074dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2075dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2076dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = sintB*cosEpsB; 2077dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2078dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2079dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2080dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2081dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2082dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = costB*sinEpsB; 2083dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2084dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2085dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2086dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2087dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2088dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2089dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xb != 0.0) { 2090dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = ((costA + costB) * (cosEpsA + cosEpsB) - 2091dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (sintA + sintB) * (sinEpsA + sinEpsB)) * xb; // approximate cosine*xb 2092dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2093dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2094dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2095dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2096dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2097dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2098dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = a + b; 2099dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 2101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 2104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Compute cosine in the first quadrant by subtracting input from PI/2 and 2105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * then calling sinQ. This is more accurate as the input approaches PI/2. 2106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xa number from which cosine is requested 2107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xb extra bits for x (may be 0.0) 2108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return cos(xa + xb) 2109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double cosQ(double xa, double xb) { 2111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double pi2a = 1.5707963267948966; 2112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double pi2b = 6.123233995736766E-17; 2113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double a = pi2a - xa; 2115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double b = -(a - pi2a + xa); 2116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b += pi2b - xb; 2117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return sinQ(a, b); 2119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 2122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Compute tangent (or cotangent) over the first quadrant. 0 < x < pi/2 2123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Use combination of table lookup and rational polynomial expansion. 2124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xa number from which sine is requested 2125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xb extra bits for x (may be 0.0) 2126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param cotanFlag if true, compute the cotangent instead of the tangent 2127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return tan(xa+xb) (or cotangent, depending on cotanFlag) 2128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double tanQ(double xa, double xb, boolean cotanFlag) { 2130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int idx = (int) ((xa * 8.0) + 0.5); 2132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double epsilon = xa - EIGHTHS[idx]; //idx*0.125; 2133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Table lookups 2135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double sintA = SINE_TABLE_A[idx]; 2136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double sintB = SINE_TABLE_B[idx]; 2137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double costA = COSINE_TABLE_A[idx]; 2138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double costB = COSINE_TABLE_B[idx]; 2139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Polynomial eval of sin(epsilon), cos(epsilon) 2141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double sinEpsA = epsilon; 2142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double sinEpsB = polySine(epsilon); 2143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double cosEpsA = 1.0; 2144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double cosEpsB = polyCosine(epsilon); 2145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Split epsilon xa + xb = x 2147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = sinEpsA * HEX_40000000; 2148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp2 = (sinEpsA + temp) - temp; 2149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond sinEpsB += sinEpsA - temp2; 2150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond sinEpsA = temp2; 2151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute sin(x) by angle addition formula */ 2153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute the following sum: 2155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB + 2157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; 2158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Ranges of elements 2160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * xxxtA 0 PI/2 2162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * xxxtB -1.5e-9 1.5e-9 2163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sinEpsA -0.0625 0.0625 2164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sinEpsB -6e-11 6e-11 2165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * cosEpsA 1.0 2166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * cosEpsB 0 -0.0625 2167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB + 2171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; 2172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //result = sintA + sintA*cosEpsB + sintB + sintB * cosEpsB; 2174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //result += costA*sinEpsA + costA*sinEpsB + costB*sinEpsA + costB * sinEpsB; 2175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double a = 0; 2176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double b = 0; 2177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute sine 2179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double t = sintA; 2180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double c = a + t; 2181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double d = -(c - a - t); 2182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = costA*sinEpsA; 2186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + sintA*cosEpsB + costA*sinEpsB; 2192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; 2193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double sina = a + b; 2195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double sinb = -(sina - a - b); 2196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute cosine 2198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = b = c = d = 0.0; 2200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = costA*cosEpsA; 2202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond t = -sintA*sinEpsA; 2208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = a + t; 2209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = -(c - a - t); 2210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = c; 2211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + d; 2212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b + costB*cosEpsA + costA*cosEpsB + costB*cosEpsB; 2214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = b - (sintB*sinEpsA + sintA*sinEpsB + sintB*sinEpsB); 2215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double cosa = a + b; 2217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double cosb = -(cosa - a - b); 2218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (cotanFlag) { 2220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmp; 2221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = cosa; cosa = sina; sina = tmp; 2222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond tmp = cosb; cosb = sinb; sinb = tmp; 2223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* estimate and correct, compute 1.0/(cosa+cosb) */ 2227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 2228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double est = (sina+sinb)/(cosa+cosb); 2229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double err = (sina - cosa*est) + (sinb - cosb*est); 2230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est += err/(cosa+cosb); 2231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond err = (sina - cosa*est) + (sinb - cosb*est); 2232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // f(x) = 1/x, f'(x) = -1/x^2 2235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double est = sina/cosa; 2237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Split the estimate to get more accurate read on division rounding */ 2239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = est * HEX_40000000; 2240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double esta = (est + temp) - temp; 2241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double estb = est - esta; 2242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = cosa * HEX_40000000; 2244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double cosaa = (cosa + temp) - temp; 2245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double cosab = cosa - cosaa; 2246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //double err = (sina - est*cosa)/cosa; // Correction for division rounding 2248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double err = (sina - esta*cosaa - esta*cosab - estb*cosaa - estb*cosab)/cosa; // Correction for division rounding 2249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond err += sinb/cosa; // Change in est due to sinb 2250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond err += -sina * cosb / cosa / cosa; // Change in est due to cosb 2251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xb != 0.0) { 2253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // tan' = 1 + tan^2 cot' = -(1 + cot^2) 2254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Approximate impact of xb 2255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xbadj = xb + est*est*xb; 2256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (cotanFlag) { 2257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xbadj = -xbadj; 2258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond err += xbadj; 2261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return est+err; 2264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Reduce the input argument using the Payne and Hanek method. 2267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This is good for all inputs 0.0 < x < inf 2268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Output is remainder after dividing by PI/2 2269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The result array should contain 3 numbers. 2270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * result[0] is the integer portion, so mod 4 this gives the quadrant. 2271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * result[1] is the upper bits of the remainder 2272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * result[2] is the lower bits of the remainder 2273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number to reduce 2275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param result placeholder where to put the result 2276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static void reducePayneHanek(double x, double result[]) 2278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond { 2279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Convert input double to bits */ 2280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long inbits = Double.doubleToLongBits(x); 2281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; 2282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Convert to fixed point representation */ 2284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond inbits &= 0x000fffffffffffffL; 2285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond inbits |= 0x0010000000000000L; 2286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Normalize input to be between 0.5 and 1.0 */ 2288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond exponent++; 2289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond inbits <<= 11; 2290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Based on the exponent, get a shifted copy of recip2pi */ 2292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long shpi0; 2293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long shpiA; 2294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long shpiB; 2295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int idx = exponent >> 6; 2296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int shift = exponent - (idx << 6); 2297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (shift != 0) { 2299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond shpi0 = (idx == 0) ? 0 : (RECIP_2PI[idx-1] << shift); 2300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond shpi0 |= RECIP_2PI[idx] >>> (64-shift); 2301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond shpiA = (RECIP_2PI[idx] << shift) | (RECIP_2PI[idx+1] >>> (64-shift)); 2302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond shpiB = (RECIP_2PI[idx+1] << shift) | (RECIP_2PI[idx+2] >>> (64-shift)); 2303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 2304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond shpi0 = (idx == 0) ? 0 : RECIP_2PI[idx-1]; 2305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond shpiA = RECIP_2PI[idx]; 2306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond shpiB = RECIP_2PI[idx+1]; 2307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply input by shpiA */ 2310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long a = inbits >>> 32; 2311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long b = inbits & 0xffffffffL; 2312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long c = shpiA >>> 32; 2314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long d = shpiA & 0xffffffffL; 2315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long ac = a * c; 2317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long bd = b * d; 2318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long bc = b * c; 2319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long ad = a * d; 2320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long prodB = bd + (ad << 32); 2322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long prodA = ac + (ad >>> 32); 2323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean bita = (bd & 0x8000000000000000L) != 0; 2325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean bitb = (ad & 0x80000000L ) != 0; 2326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean bitsum = (prodB & 0x8000000000000000L) != 0; 2327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Carry */ 2329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (bita && bitb) || 2330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ((bita || bitb) && !bitsum) ) { 2331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodA++; 2332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bita = (prodB & 0x8000000000000000L) != 0; 2335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitb = (bc & 0x80000000L ) != 0; 2336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodB = prodB + (bc << 32); 2338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodA = prodA + (bc >>> 32); 2339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitsum = (prodB & 0x8000000000000000L) != 0; 2341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Carry */ 2343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (bita && bitb) || 2344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ((bita || bitb) && !bitsum) ) { 2345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodA++; 2346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply input by shpiB */ 2349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = shpiB >>> 32; 2350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = shpiB & 0xffffffffL; 2351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ac = a * c; 2352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bc = b * c; 2353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ad = a * d; 2354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Collect terms */ 2356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ac = ac + ((bc + ad) >>> 32); 2357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bita = (prodB & 0x8000000000000000L) != 0; 2359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitb = (ac & 0x8000000000000000L ) != 0; 2360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodB += ac; 2361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitsum = (prodB & 0x8000000000000000L) != 0; 2362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Carry */ 2363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (bita && bitb) || 2364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ((bita || bitb) && !bitsum) ) { 2365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodA++; 2366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply by shpi0 */ 2369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = shpi0 >>> 32; 2370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = shpi0 & 0xffffffffL; 2371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bd = b * d; 2373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bc = b * c; 2374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ad = a * d; 2375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodA += bd + ((bc + ad) << 32); 2377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 2379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * prodA, prodB now contain the remainder as a fraction of PI. We want this as a fraction of 2380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * PI/2, so use the following steps: 2381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 1.) multiply by 4. 2382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 2.) do a fixed point muliply by PI/4. 2383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 3.) Convert to floating point. 2384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 4.) Multiply by 2 2385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* This identifies the quadrant */ 2388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int intPart = (int)(prodA >>> 62); 2389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply by 4 */ 2391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodA <<= 2; 2392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodA |= prodB >>> 62; 2393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prodB <<= 2; 2394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply by PI/4 */ 2396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = prodA >>> 32; 2397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = prodA & 0xffffffffL; 2398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = PI_O_4_BITS[0] >>> 32; 2400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = PI_O_4_BITS[0] & 0xffffffffL; 2401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ac = a * c; 2403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bd = b * d; 2404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bc = b * c; 2405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ad = a * d; 2406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long prod2B = bd + (ad << 32); 2408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long prod2A = ac + (ad >>> 32); 2409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bita = (bd & 0x8000000000000000L) != 0; 2411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitb = (ad & 0x80000000L ) != 0; 2412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitsum = (prod2B & 0x8000000000000000L) != 0; 2413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Carry */ 2415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (bita && bitb) || 2416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ((bita || bitb) && !bitsum) ) { 2417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prod2A++; 2418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bita = (prod2B & 0x8000000000000000L) != 0; 2421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitb = (bc & 0x80000000L ) != 0; 2422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prod2B = prod2B + (bc << 32); 2424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prod2A = prod2A + (bc >>> 32); 2425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitsum = (prod2B & 0x8000000000000000L) != 0; 2427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Carry */ 2429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (bita && bitb) || 2430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ((bita || bitb) && !bitsum) ) { 2431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prod2A++; 2432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply input by pio4bits[1] */ 2435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = PI_O_4_BITS[1] >>> 32; 2436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = PI_O_4_BITS[1] & 0xffffffffL; 2437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ac = a * c; 2438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bc = b * c; 2439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ad = a * d; 2440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Collect terms */ 2442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ac = ac + ((bc + ad) >>> 32); 2443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bita = (prod2B & 0x8000000000000000L) != 0; 2445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitb = (ac & 0x8000000000000000L ) != 0; 2446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prod2B += ac; 2447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitsum = (prod2B & 0x8000000000000000L) != 0; 2448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Carry */ 2449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (bita && bitb) || 2450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ((bita || bitb) && !bitsum) ) { 2451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prod2A++; 2452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply inputB by pio4bits[0] */ 2455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = prodB >>> 32; 2456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = prodB & 0xffffffffL; 2457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond c = PI_O_4_BITS[0] >>> 32; 2458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond d = PI_O_4_BITS[0] & 0xffffffffL; 2459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ac = a * c; 2460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bc = b * c; 2461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ad = a * d; 2462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Collect terms */ 2464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ac = ac + ((bc + ad) >>> 32); 2465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bita = (prod2B & 0x8000000000000000L) != 0; 2467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitb = (ac & 0x8000000000000000L ) != 0; 2468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prod2B += ac; 2469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond bitsum = (prod2B & 0x8000000000000000L) != 0; 2470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Carry */ 2471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ( (bita && bitb) || 2472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ((bita || bitb) && !bitsum) ) { 2473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond prod2A++; 2474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Convert to double */ 2477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmpA = (prod2A >>> 12) / TWO_POWER_52; // High order 52 bits 2478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double tmpB = (((prod2A & 0xfffL) << 40) + (prod2B >>> 24)) / TWO_POWER_52 / TWO_POWER_52; // Low bits 2479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double sumA = tmpA + tmpB; 2481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double sumB = -(sumA - tmpA - tmpB); 2482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Multiply by PI/2 and return */ 2484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[0] = intPart; 2485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[1] = sumA * 2.0; 2486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[2] = sumB * 2.0; 2487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 2490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Sine function. 2491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a number 2492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return sin(x) 2493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double sin(double x) { 2495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean negative = false; 2496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int quadrant = 0; 2497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xa; 2498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xb = 0.0; 2499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Take absolute value of the input */ 2501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = x; 2502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0) { 2503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negative = true; 2504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = -xa; 2505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Check for zero and negative zero */ 2508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa == 0.0) { 2509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long bits = Double.doubleToLongBits(x); 2510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (bits < 0) { 2511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -0.0; 2512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 2514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa != xa || xa == Double.POSITIVE_INFINITY) { 2517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 2518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2520dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Perform any argument reduction */ 2521dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa > 3294198.0) { 2522dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // PI * (2**20) 2523dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Argument too big for CodyWaite reduction. Must use 2524dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // PayneHanek. 2525dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double reduceResults[] = new double[3]; 2526dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond reducePayneHanek(xa, reduceResults); 2527dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadrant = ((int) reduceResults[0]) & 3; 2528dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = reduceResults[1]; 2529dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = reduceResults[2]; 2530dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (xa > 1.5707963267948966) { 2531dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Inline the Cody/Waite reduction for performance */ 2532dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2533dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Estimate k 2534dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //k = (int)(xa / 1.5707963267948966); 2535dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int k = (int)(xa * 0.6366197723675814); 2536dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2537dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute remainder 2538dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double remA; 2539dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double remB; 2540dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while (true) { 2541dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double a = -k * 1.570796251296997; 2542dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = xa + a; 2543dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB = -(remA - xa - a); 2544dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2545dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = -k * 7.549789948768648E-8; 2546dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double b = remA; 2547dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = a + b; 2548dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB += -(remA - b - a); 2549dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2550dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = -k * 6.123233995736766E-17; 2551dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = remA; 2552dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = a + b; 2553dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB += -(remA - b - a); 2554dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2555dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (remA > 0.0) 2556dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond break; 2557dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2558dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Remainder is negative, so decrement k and try again. 2559dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // This should only happen if the input is very close 2560dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // to an even multiple of pi/2 2561dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond k--; 2562dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2563dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadrant = k & 3; 2564dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = remA; 2565dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = remB; 2566dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2567dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2568dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (negative) { 2569dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadrant ^= 2; // Flip bit 1 2570dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2571dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2572dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond switch (quadrant) { 2573dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 0: 2574dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return sinQ(xa, xb); 2575dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 1: 2576dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return cosQ(xa, xb); 2577dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 2: 2578dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -sinQ(xa, xb); 2579dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 3: 2580dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -cosQ(xa, xb); 2581dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond default: 2582dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 2583dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2584dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2585dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2586dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 2587dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Cosine function 2588dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a number 2589dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return cos(x) 2590dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2591dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double cos(double x) { 2592dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int quadrant = 0; 2593dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2594dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Take absolute value of the input */ 2595dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xa = x; 2596dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0) { 2597dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = -xa; 2598dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2599dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2600dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa != xa || xa == Double.POSITIVE_INFINITY) { 2601dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 2602dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2603dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2604dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Perform any argument reduction */ 2605dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xb = 0; 2606dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa > 3294198.0) { 2607dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // PI * (2**20) 2608dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Argument too big for CodyWaite reduction. Must use 2609dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // PayneHanek. 2610dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double reduceResults[] = new double[3]; 2611dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond reducePayneHanek(xa, reduceResults); 2612dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadrant = ((int) reduceResults[0]) & 3; 2613dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = reduceResults[1]; 2614dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = reduceResults[2]; 2615dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (xa > 1.5707963267948966) { 2616dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Inline the Cody/Waite reduction for performance */ 2617dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2618dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Estimate k 2619dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //k = (int)(xa / 1.5707963267948966); 2620dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int k = (int)(xa * 0.6366197723675814); 2621dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2622dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute remainder 2623dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double remA; 2624dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double remB; 2625dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while (true) { 2626dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double a = -k * 1.570796251296997; 2627dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = xa + a; 2628dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB = -(remA - xa - a); 2629dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2630dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = -k * 7.549789948768648E-8; 2631dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double b = remA; 2632dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = a + b; 2633dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB += -(remA - b - a); 2634dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2635dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = -k * 6.123233995736766E-17; 2636dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = remA; 2637dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = a + b; 2638dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB += -(remA - b - a); 2639dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2640dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (remA > 0.0) 2641dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond break; 2642dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2643dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Remainder is negative, so decrement k and try again. 2644dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // This should only happen if the input is very close 2645dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // to an even multiple of pi/2 2646dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond k--; 2647dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2648dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadrant = k & 3; 2649dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = remA; 2650dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = remB; 2651dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2652dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2653dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //if (negative) 2654dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // quadrant = (quadrant + 2) % 4; 2655dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2656dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond switch (quadrant) { 2657dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 0: 2658dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return cosQ(xa, xb); 2659dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 1: 2660dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -sinQ(xa, xb); 2661dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 2: 2662dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -cosQ(xa, xb); 2663dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 3: 2664dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return sinQ(xa, xb); 2665dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond default: 2666dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 2667dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2668dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2669dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2670dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 2671dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Tangent function 2672dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a number 2673dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return tan(x) 2674dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2675dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double tan(double x) { 2676dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean negative = false; 2677dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int quadrant = 0; 2678dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2679dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Take absolute value of the input */ 2680dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xa = x; 2681dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0) { 2682dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negative = true; 2683dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = -xa; 2684dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2685dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2686dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Check for zero and negative zero */ 2687dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa == 0.0) { 2688dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long bits = Double.doubleToLongBits(x); 2689dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (bits < 0) { 2690dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -0.0; 2691dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2692dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 2693dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2694dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2695dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa != xa || xa == Double.POSITIVE_INFINITY) { 2696dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 2697dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2698dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2699dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Perform any argument reduction */ 2700dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xb = 0; 2701dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa > 3294198.0) { 2702dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // PI * (2**20) 2703dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Argument too big for CodyWaite reduction. Must use 2704dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // PayneHanek. 2705dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double reduceResults[] = new double[3]; 2706dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond reducePayneHanek(xa, reduceResults); 2707dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadrant = ((int) reduceResults[0]) & 3; 2708dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = reduceResults[1]; 2709dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = reduceResults[2]; 2710dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (xa > 1.5707963267948966) { 2711dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Inline the Cody/Waite reduction for performance */ 2712dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2713dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Estimate k 2714dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //k = (int)(xa / 1.5707963267948966); 2715dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int k = (int)(xa * 0.6366197723675814); 2716dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2717dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute remainder 2718dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double remA; 2719dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double remB; 2720dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while (true) { 2721dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double a = -k * 1.570796251296997; 2722dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = xa + a; 2723dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB = -(remA - xa - a); 2724dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2725dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = -k * 7.549789948768648E-8; 2726dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double b = remA; 2727dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = a + b; 2728dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB += -(remA - b - a); 2729dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2730dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond a = -k * 6.123233995736766E-17; 2731dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b = remA; 2732dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remA = a + b; 2733dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond remB += -(remA - b - a); 2734dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2735dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (remA > 0.0) 2736dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond break; 2737dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2738dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Remainder is negative, so decrement k and try again. 2739dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // This should only happen if the input is very close 2740dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // to an even multiple of pi/2 2741dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond k--; 2742dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2743dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadrant = k & 3; 2744dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = remA; 2745dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = remB; 2746dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2747dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2748dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa > 1.5) { 2749dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Accurracy suffers between 1.5 and PI/2 2750dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double pi2a = 1.5707963267948966; 2751dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double pi2b = 6.123233995736766E-17; 2752dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2753dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double a = pi2a - xa; 2754dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double b = -(a - pi2a + xa); 2755dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond b += pi2b - xb; 2756dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2757dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = a + b; 2758dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = -(xa - a - b); 2759dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond quadrant ^= 1; 2760dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negative ^= true; 2761dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2762dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2763dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result; 2764dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((quadrant & 1) == 0) { 2765dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = tanQ(xa, xb, false); 2766dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 2767dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = -tanQ(xa, xb, true); 2768dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2769dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2770dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (negative) { 2771dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = -result; 2772dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2773dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2774dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 2775dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2776dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2777dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 2778dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Arctangent function 2779dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a number 2780dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return atan(x) 2781dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2782dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double atan(double x) { 2783dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return atan(x, 0.0, false); 2784dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2785dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2786dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Internal helper function to compute arctangent. 2787dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xa number from which arctangent is requested 2788dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param xb extra bits for x (may be 0.0) 2789dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param leftPlane if true, result angle must be put in the left half plane 2790dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return atan(xa + xb) (or angle shifted by {@code PI} if leftPlane is true) 2791dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2792dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static double atan(double xa, double xb, boolean leftPlane) { 2793dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean negate = false; 2794dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int idx; 2795dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2796dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa == 0.0) { // Matches +/- 0.0; return correct sign 2797dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return leftPlane ? copySign(Math.PI, xa) : xa; 2798dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2799dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2800dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa < 0) { 2801dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // negative 2802dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = -xa; 2803dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb = -xb; 2804dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond negate = true; 2805dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2806dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2807dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa > 1.633123935319537E16) { // Very large input 2808dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (negate ^ leftPlane) ? (-Math.PI/2.0) : (Math.PI/2.0); 2809dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2810dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2811dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Estimate the closest tabulated arctan value, compute eps = xa-tangentTable */ 2812dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xa < 1.0) { 2813dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond idx = (int) (((-1.7168146928204136 * xa * xa + 8.0) * xa) + 0.5); 2814dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 2815dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = 1.0/xa; 2816dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond idx = (int) (-((-1.7168146928204136 * temp * temp + 8.0) * temp) + 13.07); 2817dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2818dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double epsA = xa - TANGENT_TABLE_A[idx]; 2819dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double epsB = -(epsA - xa + TANGENT_TABLE_A[idx]); 2820dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond epsB += xb - TANGENT_TABLE_B[idx]; 2821dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2822dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = epsA + epsB; 2823dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond epsB = -(temp - epsA - epsB); 2824dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond epsA = temp; 2825dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2826dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute eps = eps / (1.0 + xa*tangent) */ 2827dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = xa * HEX_40000000; 2828dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = xa + temp - temp; 2829dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = xb + xa - ya; 2830dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xa = ya; 2831dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond xb += yb; 2832dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2833dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //if (idx > 8 || idx == 0) 2834dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (idx == 0) { 2835dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* If the slope of the arctan is gentle enough (< 0.45), this approximation will suffice */ 2836dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //double denom = 1.0 / (1.0 + xa*tangentTableA[idx] + xb*tangentTableA[idx] + xa*tangentTableB[idx] + xb*tangentTableB[idx]); 2837dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double denom = 1.0 / (1.0 + (xa + xb) * (TANGENT_TABLE_A[idx] + TANGENT_TABLE_B[idx])); 2838dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //double denom = 1.0 / (1.0 + xa*tangentTableA[idx]); 2839dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = epsA * denom; 2840dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = epsB * denom; 2841dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 2842dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp2 = xa * TANGENT_TABLE_A[idx]; 2843dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double za = 1.0 + temp2; 2844dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double zb = -(za - 1.0 - temp2); 2845dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp2 = xb * TANGENT_TABLE_A[idx] + xa * TANGENT_TABLE_B[idx]; 2846dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = za + temp2; 2847dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb += -(temp - za - temp2); 2848dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = temp; 2849dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2850dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb += xb * TANGENT_TABLE_B[idx]; 2851dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = epsA / za; 2852dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2853dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya * HEX_40000000; 2854dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double yaa = (ya + temp) - temp; 2855dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double yab = ya - yaa; 2856dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2857dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = za * HEX_40000000; 2858dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double zaa = (za + temp) - temp; 2859dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double zab = za - zaa; 2860dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2861dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Correct for rounding in division */ 2862dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = (epsA - yaa * zaa - yaa * zab - yab * zaa - yab * zab) / za; 2863dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2864dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += -epsA * zb / za / za; 2865dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += epsB / za; 2866dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2867dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2868dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2869dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond epsA = ya; 2870dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond epsB = yb; 2871dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2872dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Evaluate polynomial */ 2873dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double epsA2 = epsA*epsA; 2874dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2875dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 2876dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = -0.09001346640161823; 2877dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + 0.11110718400605211; 2878dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + -0.1428571349122913; 2879dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + 0.19999999999273194; 2880dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + -0.33333333333333093; 2881dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 * epsA; 2882dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2883dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2884dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = 0.07490822288864472; 2885dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + -0.09088450866185192; 2886dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + 0.11111095942313305; 2887dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + -0.1428571423679182; 2888dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + 0.19999999999923582; 2889dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 + -0.33333333333333287; 2890dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = yb * epsA2 * epsA; 2891dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2892dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2893dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = epsA; 2894dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2895dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ya + yb; 2896dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = -(temp - ya - yb); 2897dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = temp; 2898dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2899dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Add in effect of epsB. atan'(x) = 1/(1+x^2) */ 2900dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += epsB / (1.0 + epsA * epsA); 2901dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2902dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result; 2903dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double resultb; 2904dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2905dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond //result = yb + eighths[idx] + ya; 2906dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double za = EIGHTHS[idx] + ya; 2907dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double zb = -(za - EIGHTHS[idx] - ya); 2908dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = za + yb; 2909dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb += -(temp - za - yb); 2910dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = temp; 2911dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2912dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = za + zb; 2913dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond resultb = -(result - za - zb); 2914dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2915dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (leftPlane) { 2916dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Result is in the left plane 2917dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double pia = 1.5707963267948966*2.0; 2918dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double pib = 6.123233995736766E-17*2.0; 2919dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2920dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = pia - result; 2921dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = -(za - pia + result); 2922dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb += pib - resultb; 2923dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2924dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = za + zb; 2925dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond resultb = -(result - za - zb); 2926dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2927dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2928dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2929dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (negate ^ leftPlane) { 2930dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = -result; 2931dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2932dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2933dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 2934dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2935dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2936dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 2937dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Two arguments arctangent function 2938dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param y ordinate 2939dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x abscissa 2940dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return phase angle of point (x,y) between {@code -PI} and {@code PI} 2941dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 2942dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double atan2(double y, double x) { 2943dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x !=x || y != y) { 2944dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 2945dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2946dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2947dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == 0.0) { 2948dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result = x*y; 2949dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double invx = 1.0/x; 2950dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double invy = 1.0/y; 2951dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2952dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (invx == 0.0) { // X is infinite 2953dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 0) { 2954dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; // return +/- 0.0 2955dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 2956dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return copySign(Math.PI, y); 2957dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2958dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2959dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2960dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0.0 || invx < 0.0) { 2961dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0.0 || invy < 0.0) { 2962dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -Math.PI; 2963dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 2964dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI; 2965dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2966dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 2967dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 2968dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2969dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2970dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2971dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // y cannot now be zero 2972dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2973dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == Double.POSITIVE_INFINITY) { 2974dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.POSITIVE_INFINITY) { 2975dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI/4.0; 2976dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2977dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2978dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.NEGATIVE_INFINITY) { 2979dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI*3.0/4.0; 2980dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2981dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2982dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI/2.0; 2983dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2984dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2985dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == Double.NEGATIVE_INFINITY) { 2986dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.POSITIVE_INFINITY) { 2987dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -Math.PI/4.0; 2988dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2989dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2990dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.NEGATIVE_INFINITY) { 2991dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -Math.PI*3.0/4.0; 2992dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2993dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2994dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -Math.PI/2.0; 2995dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 2996dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 2997dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.POSITIVE_INFINITY) { 2998dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y > 0.0 || 1/y > 0.0) { 2999dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 3000dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3001dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3002dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0.0 || 1/y < 0.0) { 3003dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -0.0; 3004dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3005dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3006dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3007dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == Double.NEGATIVE_INFINITY) 3008dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond { 3009dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y > 0.0 || 1/y > 0.0) { 3010dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI; 3011dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3012dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3013dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0.0 || 1/y < 0.0) { 3014dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -Math.PI; 3015dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3016dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3017dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3018dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Neither y nor x can be infinite or NAN here 3019dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3020dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 0) { 3021dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y > 0.0 || 1/y > 0.0) { 3022dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI/2.0; 3023dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3024dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3025dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y < 0.0 || 1/y < 0.0) { 3026dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -Math.PI/2.0; 3027dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3028dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3029dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3030dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute ratio r = y/x 3031dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double r = y/x; 3032dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(r)) { // bypass calculations that can create NaN 3033dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return atan(r, 0, x < 0); 3034dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3035dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3036dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ra = doubleHighPart(r); 3037dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double rb = r - ra; 3038dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3039dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Split x 3040dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xa = doubleHighPart(x); 3041dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xb = x - xa; 3042dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3043dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += (y - ra * xa - ra * xb - rb * xa - rb * xb) / x; 3044dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3045dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = ra + rb; 3046dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb = -(temp - ra - rb); 3047dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ra = temp; 3048dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3049dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (ra == 0) { // Fix up the sign so atan works correctly 3050dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ra = copySign(0.0, y); 3051dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3052dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3053dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Call atan 3054dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result = atan(ra, rb, x < 0); 3055dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3056dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 3057dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3058dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3059dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the arc sine of a number. 3060dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number on which evaluation is done 3061dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return arc sine of x 3062dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3063dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double asin(double x) { 3064dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x) { 3065dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 3066dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3067dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3068dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 1.0 || x < -1.0) { 3069dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 3070dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3071dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3072dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 1.0) { 3073dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI/2.0; 3074dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3075dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3076dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == -1.0) { 3077dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -Math.PI/2.0; 3078dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3079dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3080dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 0.0) { // Matches +/- 0.0; return correct sign 3081dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 3082dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3083dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3084dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute asin(x) = atan(x/sqrt(1-x*x)) */ 3085dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3086dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Split x */ 3087dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = x * HEX_40000000; 3088dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xa = x + temp - temp; 3089dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xb = x - xa; 3090dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3091dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Square it */ 3092dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = xa*xa; 3093dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = xa*xb*2.0 + xb*xb; 3094dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3095dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Subtract from 1 */ 3096dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = -ya; 3097dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = -yb; 3098dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3099dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double za = 1.0 + ya; 3100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double zb = -(za - 1.0 - ya); 3101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = za + yb; 3103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb += -(temp - za - yb); 3104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = temp; 3105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Square root */ 3107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double y; 3108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y = sqrt(za); 3109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = y * HEX_40000000; 3110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = y + temp - temp; 3111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = y - ya; 3112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Extend precision of sqrt */ 3114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y); 3115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Contribution of zb to sqrt */ 3117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double dx = zb / (2.0*y); 3118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute ratio r = x/y 3120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double r = x/y; 3121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = r * HEX_40000000; 3122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ra = r + temp - temp; 3123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double rb = r - ra; 3124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += (x - ra*ya - ra*yb - rb*ya - rb*yb) / y; // Correct for rounding in division 3126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += -x * dx / y / y; // Add in effect additional bits of sqrt. 3127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ra + rb; 3129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb = -(temp - ra - rb); 3130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ra = temp; 3131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return atan(ra, rb, false); 3133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the arc cosine of a number. 3136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number on which evaluation is done 3137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return arc cosine of x 3138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double acos(double x) { 3140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x) { 3141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 3142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x > 1.0 || x < -1.0) { 3145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 3146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == -1.0) { 3149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI; 3150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 1.0) { 3153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0.0; 3154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 0) { 3157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI/2.0; 3158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Compute acos(x) = atan(sqrt(1-x*x)/x) */ 3161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Split x */ 3163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = x * HEX_40000000; 3164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xa = x + temp - temp; 3165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xb = x - xa; 3166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Square it */ 3168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = xa*xa; 3169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = xa*xb*2.0 + xb*xb; 3170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Subtract from 1 */ 3172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = -ya; 3173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = -yb; 3174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double za = 1.0 + ya; 3176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double zb = -(za - 1.0 - ya); 3177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = za + yb; 3179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb += -(temp - za - yb); 3180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = temp; 3181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Square root */ 3183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double y = sqrt(za); 3184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = y * HEX_40000000; 3185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ya = y + temp - temp; 3186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = y - ya; 3187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Extend precision of sqrt */ 3189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y); 3190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Contribution of zb to sqrt */ 3192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb += zb / (2.0*y); 3193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y = ya+yb; 3194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond yb = -(y - ya - yb); 3195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Compute ratio r = y/x 3197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double r = y/x; 3198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Did r overflow? 3200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(r)) { // x is effectively zero 3201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Math.PI/2; // so return the appropriate value 3202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ra = doubleHighPart(r); 3205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double rb = r - ra; 3206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += (y - ra*xa - ra*xb - rb*xa - rb*xb) / x; // Correct for rounding in division 3208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb += yb / x; // Add in effect additional bits of sqrt. 3209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = ra + rb; 3211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond rb = -(temp - ra - rb); 3212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ra = temp; 3213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return atan(ra, rb, x<0); 3215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the cubic root of a number. 3218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number on which evaluation is done 3219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return cubic root of x 3220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double cbrt(double x) { 3222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Convert input double to bits */ 3223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long inbits = Double.doubleToLongBits(x); 3224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; 3225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean subnormal = false; 3226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (exponent == -1023) { 3228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x == 0) { 3229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 3230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Subnormal, so normalize */ 3233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond subnormal = true; 3234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x *= 1.8014398509481984E16; // 2^54 3235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond inbits = Double.doubleToLongBits(x); 3236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; 3237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (exponent == 1024) { 3240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Nan or infinity. Don't care which. 3241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 3242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Divide the exponent by 3 */ 3245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int exp3 = exponent / 3; 3246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* p2 will be the nearest power of 2 to x with its exponent divided by 3 */ 3248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double p2 = Double.longBitsToDouble((inbits & 0x8000000000000000L) | 3249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (long)(((exp3 + 1023) & 0x7ff)) << 52); 3250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* This will be a number between 1 and 2 */ 3252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double mant = Double.longBitsToDouble((inbits & 0x000fffffffffffffL) | 0x3ff0000000000000L); 3253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Estimate the cube root of mant by polynomial */ 3255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double est = -0.010714690733195933; 3256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est = est * mant + 0.0875862700108075; 3257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est = est * mant + -0.3058015757857271; 3258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est = est * mant + 0.7249995199969751; 3259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est = est * mant + 0.5039018405998233; 3260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est *= CBRTTWO[exponent % 3 + 2]; 3262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // est should now be good to about 15 bits of precision. Do 2 rounds of 3264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Newton's method to get closer, this should get us full double precision 3265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Scale down x for the purpose of doing newtons method. This avoids over/under flows. 3266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double xs = x / (p2*p2*p2); 3267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est += (xs - est*est*est) / (3*est*est); 3268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est += (xs - est*est*est) / (3*est*est); 3269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Do one round of Newton's method in extended precision to get the last bit right. 3271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp = est * HEX_40000000; 3272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ya = est + temp - temp; 3273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double yb = est - ya; 3274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double za = ya * ya; 3276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double zb = ya * yb * 2.0 + yb * yb; 3277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond temp = za * HEX_40000000; 3278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double temp2 = za + temp - temp; 3279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb += za - temp2; 3280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = temp2; 3281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond zb = za * yb + ya * zb + zb * yb; 3283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond za = za * ya; 3284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double na = xs - za; 3286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double nb = -(na - xs + za); 3287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond nb -= zb; 3288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est += (na+nb)/(3*est*est); 3290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* Scale by a power of two, so this is exact. */ 3292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est *= p2; 3293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (subnormal) { 3295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond est *= 3.814697265625E-6; // 2^-18 3296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return est; 3299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Convert degrees to radians, with error of less than 0.5 ULP 3303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x angle in degrees 3304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return x converted into radians 3305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double toRadians(double x) 3307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond { 3308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(x) || x == 0.0) { // Matches +/- 0.0; return correct sign 3309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 3310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // These are PI/180 split into high and low order bits 3313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double facta = 0.01745329052209854; 3314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double factb = 1.997844754509471E-9; 3315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xa = doubleHighPart(x); 3317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xb = x - xa; 3318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result = xb * factb + xb * facta + xa * factb + xa * facta; 3320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (result == 0) { 3321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = result * x; // ensure correct sign if calculation underflows 3322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 3324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Convert radians to degrees, with error of less than 0.5 ULP 3328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x angle in radians 3329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return x converted into degrees 3330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double toDegrees(double x) 3332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond { 3333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(x) || x == 0.0) { // Matches +/- 0.0; return correct sign 3334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 3335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // These are 180/PI split into high and low order bits 3338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double facta = 57.2957763671875; 3339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double factb = 3.145894820876798E-6; 3340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xa = doubleHighPart(x); 3342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double xb = x - xa; 3343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return xb * factb + xb * facta + xa * factb + xa * facta; 3345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Absolute value. 3349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which absolute value is requested 3350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return abs(x) 3351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static int abs(final int x) { 3353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (x < 0) ? -x : x; 3354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Absolute value. 3358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which absolute value is requested 3359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return abs(x) 3360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static long abs(final long x) { 3362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (x < 0l) ? -x : x; 3363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Absolute value. 3367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which absolute value is requested 3368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return abs(x) 3369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float abs(final float x) { 3371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (x < 0.0f) ? -x : (x == 0.0f) ? 0.0f : x; // -0.0 => +0.0 3372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Absolute value. 3376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which absolute value is requested 3377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return abs(x) 3378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double abs(double x) { 3380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (x < 0.0) ? -x : (x == 0.0) ? 0.0 : x; // -0.0 => +0.0 3381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Compute least significant bit (Unit in Last Position) for a number. 3385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which ulp is requested 3386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return ulp(x) 3387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double ulp(double x) { 3389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(x)) { 3390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 3391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return abs(x - Double.longBitsToDouble(Double.doubleToLongBits(x) ^ 1)); 3393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Compute least significant bit (Unit in Last Position) for a number. 3397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which ulp is requested 3398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return ulp(x) 3399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float ulp(float x) { 3401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Float.isInfinite(x)) { 3402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.POSITIVE_INFINITY; 3403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return abs(x - Float.intBitsToFloat(Float.floatToIntBits(x) ^ 1)); 3405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Multiply a double number by a power of 2. 3409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param d number to multiply 3410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param n power of 2 3411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return d × 2<sup>n</sup> 3412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double scalb(final double d, final int n) { 3414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // first simple and fast handling when 2^n can be represented using normal numbers 3416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((n > -1023) && (n < 1024)) { 3417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return d * Double.longBitsToDouble(((long) (n + 1023)) << 52); 3418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // handle special cases 3421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isNaN(d) || Double.isInfinite(d) || (d == 0)) { 3422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return d; 3423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n < -2098) { 3425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (d > 0) ? 0.0 : -0.0; 3426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n > 2097) { 3428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (d > 0) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; 3429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // decompose d 3432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final long bits = Double.doubleToLongBits(d); 3433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final long sign = bits & 0x8000000000000000L; 3434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int exponent = ((int) (bits >>> 52)) & 0x7ff; 3435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long mantissa = bits & 0x000fffffffffffffL; 3436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // compute scaled exponent 3438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int scaledExponent = exponent + n; 3439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n < 0) { 3441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // we are really in the case n <= -1023 3442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (scaledExponent > 0) { 3443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // both the input and the result are normal numbers, we only adjust the exponent 3444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); 3445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (scaledExponent > -53) { 3446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // the input is a normal number and the result is a subnormal number 3447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // recover the hidden mantissa bit 3449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa = mantissa | (1L << 52); 3450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // scales down complete mantissa, hence losing least significant bits 3452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final long mostSignificantLostBit = mantissa & (1L << (-scaledExponent)); 3453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa = mantissa >>> (1 - scaledExponent); 3454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (mostSignificantLostBit != 0) { 3455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // we need to add 1 bit to round up the result 3456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa++; 3457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.longBitsToDouble(sign | mantissa); 3459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // no need to compute the mantissa, the number scales down to 0 3462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (sign == 0L) ? 0.0 : -0.0; 3463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // we are really in the case n >= 1024 3466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (exponent == 0) { 3467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // the input number is subnormal, normalize it 3469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while ((mantissa >>> 52) != 1) { 3470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa = mantissa << 1; 3471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond --scaledExponent; 3472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ++scaledExponent; 3474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa = mantissa & 0x000fffffffffffffL; 3475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (scaledExponent < 2047) { 3477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); 3478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; 3480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (scaledExponent < 2047) { 3483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); 3484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; 3486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Multiply a float number by a power of 2. 3493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param f number to multiply 3494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param n power of 2 3495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return f × 2<sup>n</sup> 3496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float scalb(final float f, final int n) { 3498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // first simple and fast handling when 2^n can be represented using normal numbers 3500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((n > -127) && (n < 128)) { 3501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return f * Float.intBitsToFloat((n + 127) << 23); 3502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // handle special cases 3505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Float.isNaN(f) || Float.isInfinite(f) || (f == 0f)) { 3506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return f; 3507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n < -277) { 3509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (f > 0) ? 0.0f : -0.0f; 3510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n > 276) { 3512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (f > 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY; 3513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // decompose f 3516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int bits = Float.floatToIntBits(f); 3517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int sign = bits & 0x80000000; 3518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int exponent = (bits >>> 23) & 0xff; 3519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int mantissa = bits & 0x007fffff; 3520dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3521dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // compute scaled exponent 3522dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int scaledExponent = exponent + n; 3523dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3524dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n < 0) { 3525dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // we are really in the case n <= -127 3526dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (scaledExponent > 0) { 3527dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // both the input and the result are normal numbers, we only adjust the exponent 3528dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa); 3529dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (scaledExponent > -24) { 3530dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // the input is a normal number and the result is a subnormal number 3531dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3532dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // recover the hidden mantissa bit 3533dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa = mantissa | (1 << 23); 3534dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3535dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // scales down complete mantissa, hence losing least significant bits 3536dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int mostSignificantLostBit = mantissa & (1 << (-scaledExponent)); 3537dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa = mantissa >>> (1 - scaledExponent); 3538dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (mostSignificantLostBit != 0) { 3539dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // we need to add 1 bit to round up the result 3540dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa++; 3541dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3542dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.intBitsToFloat(sign | mantissa); 3543dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3544dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3545dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // no need to compute the mantissa, the number scales down to 0 3546dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (sign == 0) ? 0.0f : -0.0f; 3547dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3548dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3549dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // we are really in the case n >= 128 3550dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (exponent == 0) { 3551dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3552dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // the input number is subnormal, normalize it 3553dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while ((mantissa >>> 23) != 1) { 3554dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa = mantissa << 1; 3555dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond --scaledExponent; 3556dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3557dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ++scaledExponent; 3558dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond mantissa = mantissa & 0x007fffff; 3559dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3560dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (scaledExponent < 255) { 3561dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa); 3562dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3563dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY; 3564dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3565dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3566dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (scaledExponent < 255) { 3567dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa); 3568dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3569dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY; 3570dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3571dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3572dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3573dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3574dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3575dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3576dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get the next machine representable number after a number, moving 3577dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * in the direction of another number. 3578dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3579dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ordering is as follows (increasing): 3580dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 3581dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>-INFINITY</li> 3582dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>-MAX_VALUE</li> 3583dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>-MIN_VALUE</li> 3584dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>-0.0</li> 3585dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>+0.0</li> 3586dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>+MIN_VALUE</li> 3587dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>+MAX_VALUE</li> 3588dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>+INFINITY</li> 3589dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li></li> 3590dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3591dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If arguments compare equal, then the second argument is returned. 3592dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3593dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If {@code direction} is greater than {@code d}, 3594dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the smallest machine representable number strictly greater than 3595dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@code d} is returned; if less, then the largest representable number 3596dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * strictly less than {@code d} is returned.</p> 3597dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3598dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If {@code d} is infinite and direction does not 3599dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * bring it back to finite numbers, it is returned unchanged.</p> 3600dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 3601dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param d base number 3602dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param direction (the only important thing is whether 3603dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@code direction} is greater or smaller than {@code d}) 3604dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the next machine representable number in the specified direction 3605dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3606dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double nextAfter(double d, double direction) { 3607dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3608dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // handling of some important special cases 3609dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isNaN(d) || Double.isNaN(direction)) { 3610dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 3611dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (d == direction) { 3612dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return direction; 3613dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (Double.isInfinite(d)) { 3614dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (d < 0) ? -Double.MAX_VALUE : Double.MAX_VALUE; 3615dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (d == 0) { 3616dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE; 3617dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3618dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // special cases MAX_VALUE to infinity and MIN_VALUE to 0 3619dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // are handled just as normal numbers 3620dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3621dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final long bits = Double.doubleToLongBits(d); 3622dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final long sign = bits & 0x8000000000000000L; 3623dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((direction < d) ^ (sign == 0L)) { 3624dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) + 1)); 3625dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3626dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) - 1)); 3627dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3628dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3629dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3630dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3631dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3632dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get the next machine representable number after a number, moving 3633dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * in the direction of another number. 3634dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3635dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ordering is as follows (increasing): 3636dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 3637dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>-INFINITY</li> 3638dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>-MAX_VALUE</li> 3639dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>-MIN_VALUE</li> 3640dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>-0.0</li> 3641dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>+0.0</li> 3642dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>+MIN_VALUE</li> 3643dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>+MAX_VALUE</li> 3644dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>+INFINITY</li> 3645dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li></li> 3646dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3647dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If arguments compare equal, then the second argument is returned. 3648dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3649dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If {@code direction} is greater than {@code f}, 3650dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the smallest machine representable number strictly greater than 3651dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@code f} is returned; if less, then the largest representable number 3652dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * strictly less than {@code f} is returned.</p> 3653dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3654dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If {@code f} is infinite and direction does not 3655dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * bring it back to finite numbers, it is returned unchanged.</p> 3656dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 3657dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param f base number 3658dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param direction (the only important thing is whether 3659dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@code direction} is greater or smaller than {@code f}) 3660dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the next machine representable number in the specified direction 3661dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3662dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float nextAfter(final float f, final double direction) { 3663dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3664dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // handling of some important special cases 3665dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isNaN(f) || Double.isNaN(direction)) { 3666dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.NaN; 3667dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (f == direction) { 3668dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (float) direction; 3669dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (Float.isInfinite(f)) { 3670dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (f < 0f) ? -Float.MAX_VALUE : Float.MAX_VALUE; 3671dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (f == 0f) { 3672dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (direction < 0) ? -Float.MIN_VALUE : Float.MIN_VALUE; 3673dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3674dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // special cases MAX_VALUE to infinity and MIN_VALUE to 0 3675dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // are handled just as normal numbers 3676dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3677dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int bits = Float.floatToIntBits(f); 3678dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int sign = bits & 0x80000000; 3679dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((direction < f) ^ (sign == 0)) { 3680dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) + 1)); 3681dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3682dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) - 1)); 3683dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3684dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3685dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3686dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3687dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Get the largest whole number smaller than x. 3688dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which floor is requested 3689dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a double number f such that f is an integer f <= x < f + 1.0 3690dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3691dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double floor(double x) { 3692dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long y; 3693dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3694dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x) { // NaN 3695dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 3696dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3697dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3698dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x >= TWO_POWER_52 || x <= -TWO_POWER_52) { 3699dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 3700dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3701dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3702dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y = (long) x; 3703dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < 0 && y != x) { 3704dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y--; 3705dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3706dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3707dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == 0) { 3708dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x*y; 3709dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3710dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3711dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; 3712dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3713dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3714dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Get the smallest whole number larger than x. 3715dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which ceil is requested 3716dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a double number c such that c is an integer c - 1.0 < x <= c 3717dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3718dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double ceil(double x) { 3719dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double y; 3720dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3721dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x != x) { // NaN 3722dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x; 3723dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3724dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3725dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y = floor(x); 3726dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == x) { 3727dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; 3728dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3729dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3730dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond y += 1.0; 3731dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3732dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == 0) { 3733dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x*y; 3734dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3735dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3736dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; 3737dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3738dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3739dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Get the whole number that is the nearest to x, or the even one if x is exactly half way between two integers. 3740dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which nearest whole number is requested 3741dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a double number r such that r is an integer r - 0.5 <= x <= r + 0.5 3742dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3743dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double rint(double x) { 3744dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double y = floor(x); 3745dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double d = x - y; 3746dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3747dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (d > 0.5) { 3748dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (y == -1.0) { 3749dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -0.0; // Preserve sign of operand 3750dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3751dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y+1.0; 3752dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3753dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (d < 0.5) { 3754dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return y; 3755dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3756dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3757dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* half way, round to even */ 3758dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long z = (long) y; 3759dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (z & 1) == 0 ? y : y + 1.0; 3760dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3761dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3762dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Get the closest long to x. 3763dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which closest long is requested 3764dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return closest long to x 3765dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3766dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static long round(double x) { 3767dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (long) floor(x + 0.5); 3768dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3769dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3770dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Get the closest int to x. 3771dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x number from which closest int is requested 3772dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return closest int to x 3773dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3774dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static int round(final float x) { 3775dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (int) floor(x + 0.5f); 3776dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3777dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3778dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the minimum of two values 3779dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first value 3780dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second value 3781dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a if a is lesser or equal to b, b otherwise 3782dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3783dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static int min(final int a, final int b) { 3784dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (a <= b) ? a : b; 3785dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3786dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3787dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the minimum of two values 3788dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first value 3789dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second value 3790dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a if a is lesser or equal to b, b otherwise 3791dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3792dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static long min(final long a, final long b) { 3793dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (a <= b) ? a : b; 3794dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3795dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3796dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the minimum of two values 3797dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first value 3798dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second value 3799dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a if a is lesser or equal to b, b otherwise 3800dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3801dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float min(final float a, final float b) { 3802dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a > b) { 3803dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return b; 3804dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3805dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a < b) { 3806dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a; 3807dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3808dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* if either arg is NaN, return NaN */ 3809dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a != b) { 3810dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.NaN; 3811dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3812dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* min(+0.0,-0.0) == -0.0 */ 3813dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 0x80000000 == Float.floatToRawIntBits(-0.0d) */ 3814dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int bits = Float.floatToRawIntBits(a); 3815dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (bits == 0x80000000) { 3816dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a; 3817dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3818dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return b; 3819dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3820dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3821dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the minimum of two values 3822dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first value 3823dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second value 3824dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a if a is lesser or equal to b, b otherwise 3825dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3826dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double min(final double a, final double b) { 3827dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a > b) { 3828dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return b; 3829dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3830dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a < b) { 3831dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a; 3832dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3833dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* if either arg is NaN, return NaN */ 3834dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a != b) { 3835dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 3836dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3837dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* min(+0.0,-0.0) == -0.0 */ 3838dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */ 3839dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long bits = Double.doubleToRawLongBits(a); 3840dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (bits == 0x8000000000000000L) { 3841dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a; 3842dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3843dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return b; 3844dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3845dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3846dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the maximum of two values 3847dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first value 3848dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second value 3849dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return b if a is lesser or equal to b, a otherwise 3850dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3851dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static int max(final int a, final int b) { 3852dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (a <= b) ? b : a; 3853dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3854dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3855dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the maximum of two values 3856dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first value 3857dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second value 3858dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return b if a is lesser or equal to b, a otherwise 3859dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3860dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static long max(final long a, final long b) { 3861dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (a <= b) ? b : a; 3862dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3863dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3864dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the maximum of two values 3865dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first value 3866dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second value 3867dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return b if a is lesser or equal to b, a otherwise 3868dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3869dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float max(final float a, final float b) { 3870dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a > b) { 3871dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a; 3872dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3873dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a < b) { 3874dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return b; 3875dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3876dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* if either arg is NaN, return NaN */ 3877dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a != b) { 3878dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Float.NaN; 3879dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3880dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* min(+0.0,-0.0) == -0.0 */ 3881dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 0x80000000 == Float.floatToRawIntBits(-0.0d) */ 3882dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int bits = Float.floatToRawIntBits(a); 3883dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (bits == 0x80000000) { 3884dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return b; 3885dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3886dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a; 3887dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3888dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3889dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Compute the maximum of two values 3890dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param a first value 3891dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param b second value 3892dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return b if a is lesser or equal to b, a otherwise 3893dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3894dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double max(final double a, final double b) { 3895dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a > b) { 3896dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a; 3897dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3898dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a < b) { 3899dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return b; 3900dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3901dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* if either arg is NaN, return NaN */ 3902dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (a != b) { 3903dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 3904dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3905dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* min(+0.0,-0.0) == -0.0 */ 3906dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */ 3907dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long bits = Double.doubleToRawLongBits(a); 3908dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (bits == 0x8000000000000000L) { 3909dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return b; 3910dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3911dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return a; 3912dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3913dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3914dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3915dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the hypotenuse of a triangle with sides {@code x} and {@code y} 3916dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * - sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>)<br/> 3917dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * avoiding intermediate overflow or underflow. 3918dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 3919dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 3920dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li> If either argument is infinite, then the result is positive infinity.</li> 3921dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li> else, if either argument is NaN then the result is NaN.</li> 3922dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul> 3923dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 3924dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x a value 3925dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param y a value 3926dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>) 3927dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3928dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double hypot(final double x, final double y) { 3929dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(x) || Double.isInfinite(y)) { 3930dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.POSITIVE_INFINITY; 3931dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (Double.isNaN(x) || Double.isNaN(y)) { 3932dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Double.NaN; 3933dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3934dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3935dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int expX = getExponent(x); 3936dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int expY = getExponent(y); 3937dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (expX > expY + 27) { 3938dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // y is neglectible with respect to x 3939dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return abs(x); 3940dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (expY > expX + 27) { 3941dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // x is neglectible with respect to y 3942dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return abs(y); 3943dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 3944dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3945dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // find an intermediate scale to avoid both overflow and underflow 3946dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int middleExp = (expX + expY) / 2; 3947dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3948dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // scale parameters without losing precision 3949dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double scaledX = scalb(x, -middleExp); 3950dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double scaledY = scalb(y, -middleExp); 3951dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3952dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // compute scaled hypotenuse 3953dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double scaledH = sqrt(scaledX * scaledX + scaledY * scaledY); 3954dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3955dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // remove scaling 3956dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return scalb(scaledH, middleExp); 3957dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3958dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3959dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3960dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3961dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3962dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3963dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3964dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Computes the remainder as prescribed by the IEEE 754 standard. 3965dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The remainder value is mathematically equal to {@code x - y*n} 3966dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * where {@code n} is the mathematical integer closest to the exact mathematical value 3967dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the quotient {@code x/y}. 3968dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If two mathematical integers are equally close to {@code x/y} then 3969dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@code n} is the integer that is even. 3970dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 3971dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 3972dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>If either operand is NaN, the result is NaN.</li> 3973dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>If the result is not NaN, the sign of the result equals the sign of the dividend.</li> 3974dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.</li> 3975dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>If the dividend is finite and the divisor is an infinity, the result equals the dividend.</li> 3976dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>If the dividend is a zero and the divisor is finite, the result equals the dividend.</li> 3977dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul> 3978dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p><b>Note:</b> this implementation currently delegates to {@link StrictMath#IEEEremainder} 3979dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param dividend the number to be divided 3980dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param divisor the number by which to divide 3981dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the remainder, rounded 3982dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3983dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double IEEEremainder(double dividend, double divisor) { 3984dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return StrictMath.IEEEremainder(dividend, divisor); // TODO provide our own implementation 3985dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 3986dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 3987dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 3988dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the first argument with the sign of the second argument. 3989dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * A NaN {@code sign} argument is treated as positive. 3990dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 3991dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param magnitude the value to return 3992dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param sign the sign for the returned value 3993dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the magnitude with the same sign as the {@code sign} argument 3994dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 3995dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static double copySign(double magnitude, double sign){ 3996dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long m = Double.doubleToLongBits(magnitude); 3997dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond long s = Double.doubleToLongBits(sign); 3998dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK 3999dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return magnitude; 4000dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 4001dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -magnitude; // flip sign 4002dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 4003dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 4004dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 4005dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the first argument with the sign of the second argument. 4006dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * A NaN {@code sign} argument is treated as positive. 4007dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 4008dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param magnitude the value to return 4009dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param sign the sign for the returned value 4010dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the magnitude with the same sign as the {@code sign} argument 4011dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 4012dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static float copySign(float magnitude, float sign){ 4013dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int m = Float.floatToIntBits(magnitude); 4014dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int s = Float.floatToIntBits(sign); 4015dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK 4016dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return magnitude; 4017dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 4018dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return -magnitude; // flip sign 4019dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 4020dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 4021dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 4022dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Return the exponent of a double number, removing the bias. 4023dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 4024dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For double numbers of the form 2<sup>x</sup>, the unbiased 4025dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * exponent is exactly x. 4026dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 4027dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param d number from which exponent is requested 4028dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return exponent for d in IEEE754 representation, without bias 4029dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 4030dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static int getExponent(final double d) { 4031dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (int) ((Double.doubleToLongBits(d) >>> 52) & 0x7ff) - 1023; 4032dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 4033dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 4034dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 4035dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Return the exponent of a float number, removing the bias. 4036dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 4037dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For float numbers of the form 2<sup>x</sup>, the unbiased 4038dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * exponent is exactly x. 4039dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 4040dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param f number from which exponent is requested 4041dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return exponent for d in IEEE754 representation, without bias 4042dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 4043dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static int getExponent(final float f) { 4044dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ((Float.floatToIntBits(f) >>> 23) & 0xff) - 127; 4045dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 4046dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 4047dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond} 4048