FastMath.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.util;

  22. import org.hipparchus.CalculusFieldElement;
  23. import org.hipparchus.exception.LocalizedCoreFormats;
  24. import org.hipparchus.exception.MathRuntimeException;

  25. /**
  26.  * Faster, more accurate, portable alternative to {@link Math} and
  27.  * {@link StrictMath} for large scale computation.
  28.  * <p>
  29.  * FastMath is a drop-in replacement for both Math and StrictMath. This
  30.  * means that for any method in Math (say {@code Math.sin(x)} or
  31.  * {@code Math.cbrt(y)}), user can directly change the class and use the
  32.  * methods as is (using {@code FastMath.sin(x)} or {@code FastMath.cbrt(y)}
  33.  * in the previous example).
  34.  * <p>
  35.  * FastMath speed is achieved by relying heavily on optimizing compilers
  36.  * to native code present in many JVMs today and use of large tables.
  37.  * The larger tables are lazily initialized on first use, so that the setup
  38.  * time does not penalize methods that don't need them.
  39.  * <p>
  40.  * Note that FastMath is
  41.  * extensively used inside Hipparchus, so by calling some algorithms,
  42.  * the overhead when the the tables need to be initialized will occur
  43.  * regardless of the end-user calling FastMath methods directly or not.
  44.  * Performance figures for a specific JVM and hardware can be evaluated by
  45.  * running the FastMathTestPerformance tests in the test directory of the source
  46.  * distribution.
  47.  * <p>
  48.  * FastMath accuracy should be mostly independent of the JVM as it relies only
  49.  * on IEEE-754 basic operations and on embedded tables. Almost all operations
  50.  * are accurate to about 0.5 ulp throughout the domain range. This statement,
  51.  * of course is only a rough global observed behavior, it is <em>not</em> a
  52.  * guarantee for <em>every</em> double numbers input (see William Kahan's <a
  53.  * href="http://en.wikipedia.org/wiki/Rounding#The_table-maker.27s_dilemma">Table
  54.  * Maker's Dilemma</a>).
  55.  * <p>
  56.  * FastMath additionally implements the following methods not found in Math/StrictMath:
  57.  * <ul>
  58.  * <li>{@link #asinh(double)}</li>
  59.  * <li>{@link #acosh(double)}</li>
  60.  * <li>{@link #atanh(double)}</li>
  61.  * </ul>
  62.  * The following methods are found in Math/StrictMath since 1.6 only, they are provided
  63.  * by FastMath even in 1.5 Java virtual machines
  64.  * <ul>
  65.  * <li>{@link #copySign(double, double)}</li>
  66.  * <li>{@link #getExponent(double)}</li>
  67.  * <li>{@link #nextAfter(double,double)}</li>
  68.  * <li>{@link #nextUp(double)}</li>
  69.  * <li>{@link #scalb(double, int)}</li>
  70.  * <li>{@link #copySign(float, float)}</li>
  71.  * <li>{@link #getExponent(float)}</li>
  72.  * <li>{@link #nextAfter(float,double)}</li>
  73.  * <li>{@link #nextUp(float)}</li>
  74.  * <li>{@link #scalb(float, int)}</li>
  75.  * </ul>
  76.  */
  77. public class FastMath {
  78.     /** Archimede's constant PI, ratio of circle circumference to diameter. */
  79.     public static final double PI = 105414357.0 / 33554432.0 + 1.984187159361080883e-9;

  80.     /** Napier's constant e, base of the natural logarithm. */
  81.     public static final double E = 2850325.0 / 1048576.0 + 8.254840070411028747e-8;

  82.     /** Index of exp(0) in the array of integer exponentials. */
  83.     static final int EXP_INT_TABLE_MAX_INDEX = 750;
  84.     /** Length of the array of integer exponentials. */
  85.     static final int EXP_INT_TABLE_LEN = EXP_INT_TABLE_MAX_INDEX * 2;
  86.     /** Logarithm table length. */
  87.     static final int LN_MANT_LEN = 1024;
  88.     /** Exponential fractions table length. */
  89.     static final int EXP_FRAC_TABLE_LEN = 1025; // 0, 1/1024, ... 1024/1024

  90.     /** StrictMath.log(Double.MAX_VALUE): {@value} */
  91.     private static final double LOG_MAX_VALUE = StrictMath.log(Double.MAX_VALUE);

  92.     /** Indicator for tables initialization.
  93.      * <p>
  94.      * This compile-time constant should be set to true only if one explicitly
  95.      * wants to compute the tables at class loading time instead of using the
  96.      * already computed ones provided as literal arrays below.
  97.      * </p>
  98.      */
  99.     private static final boolean RECOMPUTE_TABLES_AT_RUNTIME = false;

  100.     /** log(2) (high bits). */
  101.     private static final double LN_2_A = 0.693147063255310059;

  102.     /** log(2) (low bits). */
  103.     private static final double LN_2_B = 1.17304635250823482e-7;

  104.     /** Coefficients for log, when input 0.99 < x < 1.01. */
  105.     private static final double[][] LN_QUICK_COEF = {
  106.         {1.0, 5.669184079525E-24},
  107.         {-0.25, -0.25},
  108.         {0.3333333134651184, 1.986821492305628E-8},
  109.         {-0.25, -6.663542893624021E-14},
  110.         {0.19999998807907104, 1.1921056801463227E-8},
  111.         {-0.1666666567325592, -7.800414592973399E-9},
  112.         {0.1428571343421936, 5.650007086920087E-9},
  113.         {-0.12502530217170715, -7.44321345601866E-11},
  114.         {0.11113807559013367, 9.219544613762692E-9},
  115.     };

  116.     /** Coefficients for log in the range of 1.0 < x < 1.0 + 2^-10. */
  117.     private static final double[][] LN_HI_PREC_COEF = {
  118.         {1.0, -6.032174644509064E-23},
  119.         {-0.25, -0.25},
  120.         {0.3333333134651184, 1.9868161777724352E-8},
  121.         {-0.2499999701976776, -2.957007209750105E-8},
  122.         {0.19999954104423523, 1.5830993332061267E-10},
  123.         {-0.16624879837036133, -2.6033824355191673E-8}
  124.     };

  125.     /** Sine, Cosine, Tangent tables are for 0, 1/8, 2/8, ... 13/8 = PI/2 approx. */

  126.     /** Sine table (high bits). */
  127.     private static final double[] SINE_TABLE_A =
  128.         {
  129.         +0.0d,
  130.         +0.1246747374534607d,
  131.         +0.24740394949913025d,
  132.         +0.366272509098053d,
  133.         +0.4794255495071411d,
  134.         +0.5850973129272461d,
  135.         +0.6816387176513672d,
  136.         +0.7675435543060303d,
  137.         +0.8414709568023682d,
  138.         +0.902267575263977d,
  139.         +0.9489846229553223d,
  140.         +0.9808930158615112d,
  141.         +0.9974949359893799d,
  142.         +0.9985313415527344d,
  143.     };

  144.     /** Sine table (low bits). */
  145.     private static final double[] SINE_TABLE_B =
  146.         {
  147.         +0.0d,
  148.         -4.068233003401932E-9d,
  149.         +9.755392680573412E-9d,
  150.         +1.9987994582857286E-8d,
  151.         -1.0902938113007961E-8d,
  152.         -3.9986783938944604E-8d,
  153.         +4.23719669792332E-8d,
  154.         -5.207000323380292E-8d,
  155.         +2.800552834259E-8d,
  156.         +1.883511811213715E-8d,
  157.         -3.5997360512765566E-9d,
  158.         +4.116164446561962E-8d,
  159.         +5.0614674548127384E-8d,
  160.         -1.0129027912496858E-9d,
  161.     };

  162.     /** Cosine table (high bits). */
  163.     private static final double[] COSINE_TABLE_A =
  164.         {
  165.         +1.0d,
  166.         +0.9921976327896118d,
  167.         +0.9689123630523682d,
  168.         +0.9305076599121094d,
  169.         +0.8775825500488281d,
  170.         +0.8109631538391113d,
  171.         +0.7316888570785522d,
  172.         +0.6409968137741089d,
  173.         +0.5403022766113281d,
  174.         +0.4311765432357788d,
  175.         +0.3153223395347595d,
  176.         +0.19454771280288696d,
  177.         +0.07073719799518585d,
  178.         -0.05417713522911072d,
  179.     };

  180.     /** Cosine table (low bits). */
  181.     private static final double[] COSINE_TABLE_B =
  182.         {
  183.         +0.0d,
  184.         +3.4439717236742845E-8d,
  185.         +5.865827662008209E-8d,
  186.         -3.7999795083850525E-8d,
  187.         +1.184154459111628E-8d,
  188.         -3.43338934259355E-8d,
  189.         +1.1795268640216787E-8d,
  190.         +4.438921624363781E-8d,
  191.         +2.925681159240093E-8d,
  192.         -2.6437112632041807E-8d,
  193.         +2.2860509143963117E-8d,
  194.         -4.813899778443457E-9d,
  195.         +3.6725170580355583E-9d,
  196.         +2.0217439756338078E-10d,
  197.     };


  198.     /** Tangent table, used by atan() (high bits). */
  199.     private static final double[] TANGENT_TABLE_A =
  200.         {
  201.         +0.0d,
  202.         +0.1256551444530487d,
  203.         +0.25534194707870483d,
  204.         +0.3936265707015991d,
  205.         +0.5463024377822876d,
  206.         +0.7214844226837158d,
  207.         +0.9315965175628662d,
  208.         +1.1974215507507324d,
  209.         +1.5574076175689697d,
  210.         +2.092571258544922d,
  211.         +3.0095696449279785d,
  212.         +5.041914939880371d,
  213.         +14.101419448852539d,
  214.         -18.430862426757812d,
  215.     };

  216.     /** Tangent table, used by atan() (low bits). */
  217.     private static final double[] TANGENT_TABLE_B =
  218.         {
  219.         +0.0d,
  220.         -7.877917738262007E-9d,
  221.         -2.5857668567479893E-8d,
  222.         +5.2240336371356666E-9d,
  223.         +5.206150291559893E-8d,
  224.         +1.8307188599677033E-8d,
  225.         -5.7618793749770706E-8d,
  226.         +7.848361555046424E-8d,
  227.         +1.0708593250394448E-7d,
  228.         +1.7827257129423813E-8d,
  229.         +2.893485277253286E-8d,
  230.         +3.1660099222737955E-7d,
  231.         +4.983191803254889E-7d,
  232.         -3.356118100840571E-7d,
  233.     };

  234.     /** Bits of 1/(2*pi), need for reducePayneHanek(). */
  235.     private static final long[] RECIP_2PI = {
  236.         (0x28be60dbL << 32) | 0x9391054aL,
  237.         (0x7f09d5f4L << 32) | 0x7d4d3770L,
  238.         (0x36d8a566L << 32) | 0x4f10e410L,
  239.         (0x7f9458eaL << 32) | 0xf7aef158L,
  240.         (0x6dc91b8eL << 32) | 0x909374b8L,
  241.         (0x01924bbaL << 32) | 0x82746487L,
  242.         (0x3f877ac7L << 32) | 0x2c4a69cfL,
  243.         (0xba208d7dL << 32) | 0x4baed121L,
  244.         (0x3a671c09L << 32) | 0xad17df90L,
  245.         (0x4e64758eL << 32) | 0x60d4ce7dL,
  246.         (0x272117e2L << 32) | 0xef7e4a0eL,
  247.         (0xc7fe25ffL << 32) | 0xf7816603L,
  248.         (0xfbcbc462L << 32) | 0xd6829b47L,
  249.         (0xdb4d9fb3L << 32) | 0xc9f2c26dL,
  250.         (0xd3d18fd9L << 32) | 0xa797fa8bL,
  251.         (0x5d49eeb1L << 32) | 0xfaf97c5eL,
  252.         (0xcf41ce7dL << 32) | 0xe294a4baL,
  253.          0x9afed7ecL << 32  };

  254.     /** Bits of pi/4, need for reducePayneHanek(). */
  255.     private static final long[] PI_O_4_BITS = {
  256.         (0xc90fdaa2L << 32) | 0x2168c234L,
  257.         (0xc4c6628bL << 32) | 0x80dc1cd1L };

  258.     /** Eighths.
  259.      * This is used by sinQ, because its faster to do a table lookup than
  260.      * a multiply in this time-critical routine
  261.      */
  262.     private static final double[]
  263.                     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};

  264.     /** Table of 2^((n+2)/3) */
  265.     private static final double[] CBRTTWO = { 0.6299605249474366,
  266.                                             0.7937005259840998,
  267.                                             1.0,
  268.                                             1.2599210498948732,
  269.                                             1.5874010519681994 };

  270.     /*
  271.      *  There are 52 bits in the mantissa of a double.
  272.      *  For additional precision, the code splits double numbers into two parts,
  273.      *  by clearing the low order 30 bits if possible, and then performs the arithmetic
  274.      *  on each half separately.
  275.      */

  276.     /**
  277.      * 0x40000000 - used to split a double into two parts, both with the low order bits cleared.
  278.      * Equivalent to 2^30.
  279.      */
  280.     private static final long HEX_40000000 = 0x40000000L; // 1073741824L

  281.     /** Mask used to clear low order 30 bits */
  282.     private static final long MASK_30BITS = -1L - (HEX_40000000 -1); // 0xFFFFFFFFC0000000L;

  283.     /** Mask used to clear the non-sign part of an int. */
  284.     private static final int MASK_NON_SIGN_INT = 0x7fffffff;

  285.     /** Mask used to clear the non-sign part of a long. */
  286.     private static final long MASK_NON_SIGN_LONG = 0x7fffffffffffffffl;

  287.     /** Mask used to extract exponent from double bits. */
  288.     private static final long MASK_DOUBLE_EXPONENT = 0x7ff0000000000000L;

  289.     /** Mask used to extract mantissa from double bits. */
  290.     private static final long MASK_DOUBLE_MANTISSA = 0x000fffffffffffffL;

  291.     /** Mask used to add implicit high order bit for normalized double. */
  292.     private static final long IMPLICIT_HIGH_BIT = 0x0010000000000000L;

  293.     /** 2^52 - double numbers this large must be integral (no fraction) or NaN or Infinite */
  294.     private static final double TWO_POWER_52 = 4503599627370496.0;

  295.     /** Constant: {@value}. */
  296.     private static final double F_1_3 = 1d / 3d;
  297.     /** Constant: {@value}. */
  298.     private static final double F_1_5 = 1d / 5d;
  299.     /** Constant: {@value}. */
  300.     private static final double F_1_7 = 1d / 7d;
  301.     /** Constant: {@value}. */
  302.     private static final double F_1_9 = 1d / 9d;
  303.     /** Constant: {@value}. */
  304.     private static final double F_1_11 = 1d / 11d;
  305.     /** Constant: {@value}. */
  306.     private static final double F_1_13 = 1d / 13d;
  307.     /** Constant: {@value}. */
  308.     private static final double F_1_15 = 1d / 15d;
  309.     /** Constant: {@value}. */
  310.     private static final double F_1_17 = 1d / 17d;
  311.     /** Constant: {@value}. */
  312.     private static final double F_3_4 = 3d / 4d;
  313.     /** Constant: {@value}. */
  314.     private static final double F_15_16 = 15d / 16d;
  315.     /** Constant: {@value}. */
  316.     private static final double F_13_14 = 13d / 14d;
  317.     /** Constant: {@value}. */
  318.     private static final double F_11_12 = 11d / 12d;
  319.     /** Constant: {@value}. */
  320.     private static final double F_9_10 = 9d / 10d;
  321.     /** Constant: {@value}. */
  322.     private static final double F_7_8 = 7d / 8d;
  323.     /** Constant: {@value}. */
  324.     private static final double F_5_6 = 5d / 6d;
  325.     /** Constant: {@value}. */
  326.     private static final double F_1_2 = 1d / 2d;
  327.     /** Constant: {@value}. */
  328.     private static final double F_1_4 = 1d / 4d;

  329.     /**
  330.      * Private Constructor
  331.      */
  332.     private FastMath() {}

  333.     // Generic helper methods

  334.     /**
  335.      * Get the high order bits from the mantissa.
  336.      * Equivalent to adding and subtracting HEX_40000 but also works for very large numbers
  337.      *
  338.      * @param d the value to split
  339.      * @return the high order part of the mantissa
  340.      */
  341.     private static double doubleHighPart(double d) {
  342.         if (d > -Precision.SAFE_MIN && d < Precision.SAFE_MIN){
  343.             return d; // These are un-normalised - don't try to convert
  344.         }
  345.         long xl = Double.doubleToRawLongBits(d); // can take raw bits because just gonna convert it back
  346.         xl &= MASK_30BITS; // Drop low order bits
  347.         return Double.longBitsToDouble(xl);
  348.     }

  349.     /** Compute the square root of a number.
  350.      * <p><b>Note:</b> this implementation currently delegates to {@link Math#sqrt}
  351.      * @param a number on which evaluation is done
  352.      * @return square root of a
  353.      */
  354.     public static double sqrt(final double a) {
  355.         return Math.sqrt(a);
  356.     }

  357.     /** Compute the hyperbolic cosine of a number.
  358.      * @param x number on which evaluation is done
  359.      * @return hyperbolic cosine of x
  360.      */
  361.     public static double cosh(double x) {
  362.       if (Double.isNaN(x)) {
  363.           return x;
  364.       }

  365.       // cosh[z] = (exp(z) + exp(-z))/2

  366.       // for numbers with magnitude 20 or so,
  367.       // exp(-z) can be ignored in comparison with exp(z)

  368.       if (x > 20) {
  369.           if (x >= LOG_MAX_VALUE) {
  370.               // Avoid overflow (MATH-905).
  371.               final double t = exp(0.5 * x);
  372.               return (0.5 * t) * t;
  373.           } else {
  374.               return 0.5 * exp(x);
  375.           }
  376.       } else if (x < -20) {
  377.           if (x <= -LOG_MAX_VALUE) {
  378.               // Avoid overflow (MATH-905).
  379.               final double t = exp(-0.5 * x);
  380.               return (0.5 * t) * t;
  381.           } else {
  382.               return 0.5 * exp(-x);
  383.           }
  384.       }

  385.       final double[] hiPrec = new double[2];
  386.       if (x < 0.0) {
  387.           x = -x;
  388.       }
  389.       exp(x, 0.0, hiPrec);

  390.       double ya = hiPrec[0] + hiPrec[1];
  391.       double yb = -(ya - hiPrec[0] - hiPrec[1]);

  392.       double temp = ya * HEX_40000000;
  393.       double yaa = ya + temp - temp;
  394.       double yab = ya - yaa;

  395.       // recip = 1/y
  396.       double recip = 1.0/ya;
  397.       temp = recip * HEX_40000000;
  398.       double recipa = recip + temp - temp;
  399.       double recipb = recip - recipa;

  400.       // Correct for rounding in division
  401.       recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip;
  402.       // Account for yb
  403.       recipb += -yb * recip * recip;

  404.       // y = y + 1/y
  405.       temp = ya + recipa;
  406.       yb += -(temp - ya - recipa);
  407.       ya = temp;
  408.       temp = ya + recipb;
  409.       yb += -(temp - ya - recipb);
  410.       ya = temp;

  411.       double result = ya + yb;
  412.       result *= 0.5;
  413.       return result;
  414.     }

  415.     /** Compute the hyperbolic sine of a number.
  416.      * @param x number on which evaluation is done
  417.      * @return hyperbolic sine of x
  418.      */
  419.     public static double sinh(double x) {
  420.       boolean negate = false;
  421.       if (Double.isNaN(x)) {
  422.           return x;
  423.       }

  424.       // sinh[z] = (exp(z) - exp(-z) / 2

  425.       // for values of z larger than about 20,
  426.       // exp(-z) can be ignored in comparison with exp(z)

  427.       if (x > 20) {
  428.           if (x >= LOG_MAX_VALUE) {
  429.               // Avoid overflow (MATH-905).
  430.               final double t = exp(0.5 * x);
  431.               return (0.5 * t) * t;
  432.           } else {
  433.               return 0.5 * exp(x);
  434.           }
  435.       } else if (x < -20) {
  436.           if (x <= -LOG_MAX_VALUE) {
  437.               // Avoid overflow (MATH-905).
  438.               final double t = exp(-0.5 * x);
  439.               return (-0.5 * t) * t;
  440.           } else {
  441.               return -0.5 * exp(-x);
  442.           }
  443.       }

  444.       if (x == 0) {
  445.           return x;
  446.       }

  447.       if (x < 0.0) {
  448.           x = -x;
  449.           negate = true;
  450.       }

  451.       double[] hiPrec = new double[2];
  452.       double result;

  453.       if (x > 0.25) {
  454.           exp(x, 0.0, hiPrec);

  455.           double ya = hiPrec[0] + hiPrec[1];
  456.           double yb = -(ya - hiPrec[0] - hiPrec[1]);

  457.           double temp = ya * HEX_40000000;
  458.           double yaa = ya + temp - temp;
  459.           double yab = ya - yaa;

  460.           // recip = 1/y
  461.           double recip = 1.0/ya;
  462.           temp = recip * HEX_40000000;
  463.           double recipa = recip + temp - temp;
  464.           double recipb = recip - recipa;

  465.           // Correct for rounding in division
  466.           recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip;
  467.           // Account for yb
  468.           recipb += -yb * recip * recip;

  469.           recipa = -recipa;
  470.           recipb = -recipb;

  471.           // y = y - 1/y
  472.           temp = ya + recipa;
  473.           yb += -(temp - ya - recipa);
  474.           ya = temp;
  475.           temp = ya + recipb;
  476.           yb += -(temp - ya - recipb);
  477.           ya = temp;

  478.           result = ya + yb;
  479.           result *= 0.5;
  480.       } else {
  481.           expm1(x, hiPrec);

  482.           double ya = hiPrec[0] + hiPrec[1];
  483.           double yb = -(ya - hiPrec[0] - hiPrec[1]);

  484.           /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */
  485.           double denom = 1.0 + ya;
  486.           double denomr = 1.0 / denom;
  487.           double denomb = -(denom - 1.0 - ya) + yb;
  488.           double ratio = ya * denomr;
  489.           double temp = ratio * HEX_40000000;
  490.           double ra = ratio + temp - temp;
  491.           double rb = ratio - ra;

  492.           temp = denom * HEX_40000000;
  493.           double za = denom + temp - temp;
  494.           double zb = denom - za;

  495.           rb += (ya - za*ra - za*rb - zb*ra - zb*rb) * denomr;

  496.           // Adjust for yb
  497.           rb += yb*denomr;                        // numerator
  498.           rb += -ya * denomb * denomr * denomr;   // denominator

  499.           // y = y - 1/y
  500.           temp = ya + ra;
  501.           yb += -(temp - ya - ra);
  502.           ya = temp;
  503.           temp = ya + rb;
  504.           yb += -(temp - ya - rb);
  505.           ya = temp;

  506.           result = ya + yb;
  507.           result *= 0.5;
  508.       }

  509.       if (negate) {
  510.           result = -result;
  511.       }

  512.       return result;
  513.     }

  514.     /**
  515.      * Combined hyperbolic sine and hyperbolic cosine function.
  516.      *
  517.      * @param x Argument.
  518.      * @return [sinh(x), cosh(x)]
  519.      */
  520.     public static SinhCosh sinhCosh(double x) {
  521.       boolean negate = false;
  522.       if (Double.isNaN(x)) {
  523.           return new SinhCosh(x, x);
  524.       }

  525.       // sinh[z] = (exp(z) - exp(-z) / 2
  526.       // cosh[z] = (exp(z) + exp(-z))/2

  527.       // for values of z larger than about 20,
  528.       // exp(-z) can be ignored in comparison with exp(z)

  529.       if (x > 20) {
  530.           final double e;
  531.           if (x >= LOG_MAX_VALUE) {
  532.               // Avoid overflow (MATH-905).
  533.               final double t = exp(0.5 * x);
  534.               e = (0.5 * t) * t;
  535.           } else {
  536.               e = 0.5 * exp(x);
  537.           }
  538.           return new SinhCosh(e, e);
  539.       } else if (x < -20) {
  540.           final double e;
  541.           if (x <= -LOG_MAX_VALUE) {
  542.               // Avoid overflow (MATH-905).
  543.               final double t = exp(-0.5 * x);
  544.               e = (-0.5 * t) * t;
  545.           } else {
  546.               e = -0.5 * exp(-x);
  547.           }
  548.           return new SinhCosh(e, -e);
  549.       }

  550.       if (x == 0) {
  551.           return new SinhCosh(x, 1.0);
  552.       }

  553.       if (x < 0.0) {
  554.           x = -x;
  555.           negate = true;
  556.       }

  557.       double[] hiPrec = new double[2];
  558.       double resultM;
  559.       double resultP;

  560.       if (x > 0.25) {
  561.           exp(x, 0.0, hiPrec);

  562.           final double ya = hiPrec[0] + hiPrec[1];
  563.           final double yb = -(ya - hiPrec[0] - hiPrec[1]);

  564.           double temp = ya * HEX_40000000;
  565.           double yaa = ya + temp - temp;
  566.           double yab = ya - yaa;

  567.           // recip = 1/y
  568.           double recip = 1.0/ya;
  569.           temp = recip * HEX_40000000;
  570.           double recipa = recip + temp - temp;
  571.           double recipb = recip - recipa;

  572.           // Correct for rounding in division
  573.           recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip;
  574.           // Account for yb
  575.           recipb += -yb * recip * recip;

  576.           // y = y - 1/y
  577.           temp = ya - recipa;
  578.           double ybM = yb - (temp - ya + recipa);
  579.           double yaM = temp;
  580.           temp = yaM - recipb;
  581.           ybM += -(temp - yaM + recipb);
  582.           yaM = temp;
  583.           resultM = yaM + ybM;
  584.           resultM *= 0.5;

  585.           // y = y + 1/y
  586.           temp = ya + recipa;
  587.           double ybP = yb - (temp - ya - recipa);
  588.           double yaP = temp;
  589.           temp = yaP + recipb;
  590.           ybP += -(temp - yaP - recipb);
  591.           yaP = temp;
  592.           resultP = yaP + ybP;
  593.           resultP *= 0.5;

  594.       } else {
  595.           expm1(x, hiPrec);

  596.           final double ya = hiPrec[0] + hiPrec[1];
  597.           final double yb = -(ya - hiPrec[0] - hiPrec[1]);

  598.           /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */
  599.           double denom = 1.0 + ya;
  600.           double denomr = 1.0 / denom;
  601.           double denomb = -(denom - 1.0 - ya) + yb;
  602.           double ratio = ya * denomr;
  603.           double temp = ratio * HEX_40000000;
  604.           double ra = ratio + temp - temp;
  605.           double rb = ratio - ra;

  606.           temp = denom * HEX_40000000;
  607.           double za = denom + temp - temp;
  608.           double zb = denom - za;

  609.           rb += (ya - za*ra - za*rb - zb*ra - zb*rb) * denomr;

  610.           // Adjust for yb
  611.           rb += yb*denomr;                        // numerator
  612.           rb += -ya * denomb * denomr * denomr;   // denominator

  613.           // y = y - 1/y
  614.           temp = ya + ra;
  615.           double ybM = yb - (temp - ya - ra);
  616.           double yaM = temp;
  617.           temp = yaM + rb;
  618.           ybM += -(temp - yaM - rb);
  619.           yaM = temp;
  620.           resultM = yaM + ybM;
  621.           resultM *= 0.5;

  622.           // y = y + 1/y + 2
  623.           temp = ya - ra;
  624.           double ybP = yb - (temp - ya + ra);
  625.           double yaP = temp;
  626.           temp = yaP - rb;
  627.           ybP += -(temp - yaP + rb);
  628.           yaP = temp;
  629.           resultP = yaP + ybP + 2;
  630.           resultP *= 0.5;
  631.       }

  632.       if (negate) {
  633.           resultM = -resultM;
  634.       }

  635.       return new SinhCosh(resultM, resultP);

  636.     }

  637.     /**
  638.      * Combined hyperbolic sine and hyperbolic cosine function.
  639.      *
  640.      * @param x Argument.
  641.      * @param <T> the type of the field element
  642.      * @return [sinh(x), cosh(x)]
  643.      */
  644.     public static <T extends CalculusFieldElement<T>> FieldSinhCosh<T> sinhCosh(T x) {
  645.         return x.sinhCosh();
  646.     }

  647.     /** Compute the hyperbolic tangent of a number.
  648.      * @param x number on which evaluation is done
  649.      * @return hyperbolic tangent of x
  650.      */
  651.     public static double tanh(double x) {
  652.       boolean negate = false;

  653.       if (Double.isNaN(x)) {
  654.           return x;
  655.       }

  656.       // tanh[z] = sinh[z] / cosh[z]
  657.       // = (exp(z) - exp(-z)) / (exp(z) + exp(-z))
  658.       // = (exp(2x) - 1) / (exp(2x) + 1)

  659.       // for magnitude > 20, sinh[z] == cosh[z] in double precision

  660.       if (x > 20.0) {
  661.           return 1.0;
  662.       }

  663.       if (x < -20) {
  664.           return -1.0;
  665.       }

  666.       if (x == 0) {
  667.           return x;
  668.       }

  669.       if (x < 0.0) {
  670.           x = -x;
  671.           negate = true;
  672.       }

  673.       double result;
  674.       if (x >= 0.5) {
  675.           double[] hiPrec = new double[2];
  676.           // tanh(x) = (exp(2x) - 1) / (exp(2x) + 1)
  677.           exp(x*2.0, 0.0, hiPrec);

  678.           double ya = hiPrec[0] + hiPrec[1];
  679.           double yb = -(ya - hiPrec[0] - hiPrec[1]);

  680.           /* Numerator */
  681.           double na = -1.0 + ya;
  682.           double nb = -(na + 1.0 - ya);
  683.           double temp = na + yb;
  684.           nb += -(temp - na - yb);
  685.           na = temp;

  686.           /* Denominator */
  687.           double da = 1.0 + ya;
  688.           double db = -(da - 1.0 - ya);
  689.           temp = da + yb;
  690.           db += -(temp - da - yb);
  691.           da = temp;

  692.           temp = da * HEX_40000000;
  693.           double daa = da + temp - temp;
  694.           double dab = da - daa;

  695.           // ratio = na/da
  696.           double ratio = na/da;
  697.           temp = ratio * HEX_40000000;
  698.           double ratioa = ratio + temp - temp;
  699.           double ratiob = ratio - ratioa;

  700.           // Correct for rounding in division
  701.           ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da;

  702.           // Account for nb
  703.           ratiob += nb / da;
  704.           // Account for db
  705.           ratiob += -db * na / da / da;

  706.           result = ratioa + ratiob;
  707.       }
  708.       else {
  709.           double[] hiPrec = new double[2];
  710.           // tanh(x) = expm1(2x) / (expm1(2x) + 2)
  711.           expm1(x*2.0, hiPrec);

  712.           double ya = hiPrec[0] + hiPrec[1];
  713.           double yb = -(ya - hiPrec[0] - hiPrec[1]);

  714.           /* Numerator */
  715.           double na = ya;
  716.           double nb = yb;

  717.           /* Denominator */
  718.           double da = 2.0 + ya;
  719.           double db = -(da - 2.0 - ya);
  720.           double temp = da + yb;
  721.           db += -(temp - da - yb);
  722.           da = temp;

  723.           temp = da * HEX_40000000;
  724.           double daa = da + temp - temp;
  725.           double dab = da - daa;

  726.           // ratio = na/da
  727.           double ratio = na/da;
  728.           temp = ratio * HEX_40000000;
  729.           double ratioa = ratio + temp - temp;
  730.           double ratiob = ratio - ratioa;

  731.           // Correct for rounding in division
  732.           ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da;

  733.           // Account for nb
  734.           ratiob += nb / da;
  735.           // Account for db
  736.           ratiob += -db * na / da / da;

  737.           result = ratioa + ratiob;
  738.       }

  739.       if (negate) {
  740.           result = -result;
  741.       }

  742.       return result;
  743.     }

  744.     /** Compute the inverse hyperbolic cosine of a number.
  745.      * @param a number on which evaluation is done
  746.      * @return inverse hyperbolic cosine of a
  747.      */
  748.     public static double acosh(final double a) {
  749.         return log(a + sqrt(a * a - 1));
  750.     }

  751.     /** Compute the inverse hyperbolic sine of a number.
  752.      * @param a number on which evaluation is done
  753.      * @return inverse hyperbolic sine of a
  754.      */
  755.     public static double asinh(double a) {
  756.         boolean negative = false;
  757.         if (a < 0) {
  758.             negative = true;
  759.             a = -a;
  760.         }

  761.         double absAsinh;
  762.         if (a > 0.167) {
  763.             absAsinh = log(sqrt(a * a + 1) + a);
  764.         } else {
  765.             final double a2 = a * a;
  766.             if (a > 0.097) {
  767.                 absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * (F_1_9 - a2 * (F_1_11 - a2 * (F_1_13 - a2 * (F_1_15 - a2 * F_1_17 * F_15_16) * F_13_14) * F_11_12) * F_9_10) * F_7_8) * F_5_6) * F_3_4) * F_1_2);
  768.             } else if (a > 0.036) {
  769.                 absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * (F_1_9 - a2 * (F_1_11 - a2 * F_1_13 * F_11_12) * F_9_10) * F_7_8) * F_5_6) * F_3_4) * F_1_2);
  770.             } else if (a > 0.0036) {
  771.                 absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * F_1_9 * F_7_8) * F_5_6) * F_3_4) * F_1_2);
  772.             } else {
  773.                 absAsinh = a * (1 - a2 * (F_1_3 - a2 * F_1_5 * F_3_4) * F_1_2);
  774.             }
  775.         }

  776.         return negative ? -absAsinh : absAsinh;
  777.     }

  778.     /** Compute the inverse hyperbolic tangent of a number.
  779.      * @param a number on which evaluation is done
  780.      * @return inverse hyperbolic tangent of a
  781.      */
  782.     public static double atanh(double a) {
  783.         boolean negative = false;
  784.         if (a < 0) {
  785.             negative = true;
  786.             a = -a;
  787.         }

  788.         double absAtanh;
  789.         if (a > 0.15) {
  790.             absAtanh = 0.5 * log((1 + a) / (1 - a));
  791.         } else {
  792.             final double a2 = a * a;
  793.             if (a > 0.087) {
  794.                 absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * (F_1_9 + a2 * (F_1_11 + a2 * (F_1_13 + a2 * (F_1_15 + a2 * F_1_17))))))));
  795.             } else if (a > 0.031) {
  796.                 absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * (F_1_9 + a2 * (F_1_11 + a2 * F_1_13))))));
  797.             } else if (a > 0.003) {
  798.                 absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * F_1_9))));
  799.             } else {
  800.                 absAtanh = a * (1 + a2 * (F_1_3 + a2 * F_1_5));
  801.             }
  802.         }

  803.         return negative ? -absAtanh : absAtanh;
  804.     }

  805.     /** Compute the signum of a number.
  806.      * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise
  807.      * @param a number on which evaluation is done
  808.      * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
  809.      */
  810.     public static double signum(final double a) {
  811.         return (a < 0.0) ? -1.0 : ((a > 0.0) ? 1.0 : a); // return +0.0/-0.0/NaN depending on a
  812.     }

  813.     /** Compute the signum of a number.
  814.      * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise
  815.      * @param a number on which evaluation is done
  816.      * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
  817.      */
  818.     public static float signum(final float a) {
  819.         return (a < 0.0f) ? -1.0f : ((a > 0.0f) ? 1.0f : a); // return +0.0/-0.0/NaN depending on a
  820.     }

  821.     /** Compute next number towards positive infinity.
  822.      * @param a number to which neighbor should be computed
  823.      * @return neighbor of a towards positive infinity
  824.      */
  825.     public static double nextUp(final double a) {
  826.         return nextAfter(a, Double.POSITIVE_INFINITY);
  827.     }

  828.     /** Compute next number towards positive infinity.
  829.      * @param a number to which neighbor should be computed
  830.      * @return neighbor of a towards positive infinity
  831.      */
  832.     public static float nextUp(final float a) {
  833.         return nextAfter(a, Float.POSITIVE_INFINITY);
  834.     }

  835.     /** Compute next number towards negative infinity.
  836.      * @param a number to which neighbor should be computed
  837.      * @return neighbor of a towards negative infinity
  838.      */
  839.     public static double nextDown(final double a) {
  840.         return nextAfter(a, Double.NEGATIVE_INFINITY);
  841.     }

  842.     /** Compute next number towards negative infinity.
  843.      * @param a number to which neighbor should be computed
  844.      * @return neighbor of a towards negative infinity
  845.      */
  846.     public static float nextDown(final float a) {
  847.         return nextAfter(a, Float.NEGATIVE_INFINITY);
  848.     }

  849.     /** Clamp a value within an interval.
  850.      * @param value value to clamp
  851.      * @param inf lower bound of the clamping interval
  852.      * @param sup upper bound of the clamping interval
  853.      * @return value clamped within [inf; sup], or value if already within bounds.
  854.      * @since 3.0
  855.      */
  856.     public static int clamp(final int value, final int inf, final int sup) {
  857.         return max(inf, min(value, sup));
  858.     }

  859.     /** Clamp a value within an interval.
  860.      * @param value value to clamp
  861.      * @param inf lower bound of the clamping interval
  862.      * @param sup upper bound of the clamping interval
  863.      * @return value clamped within [inf; sup], or value if already within bounds.
  864.      * @since 3.0
  865.      */
  866.     public static long clamp(final long value, final long inf, final long sup) {
  867.         return max(inf, min(value, sup));
  868.     }

  869.     /** Clamp a value within an interval.
  870.      * @param value value to clamp
  871.      * @param inf lower bound of the clamping interval
  872.      * @param sup upper bound of the clamping interval
  873.      * @return value clamped within [inf; sup], or value if already within bounds.
  874.      * @since 3.0
  875.      */
  876.     public static int clamp(final long value, final int inf, final int sup) {
  877.         return (int) max(inf, min(value, sup));
  878.     }

  879.     /** Clamp a value within an interval.
  880.      * <p>
  881.      * This method assumes -0.0 is below +0.0
  882.      * </p>
  883.      * @param value value to clamp
  884.      * @param inf lower bound of the clamping interval
  885.      * @param sup upper bound of the clamping interval
  886.      * @return value clamped within [inf; sup], or value if already within bounds.
  887.      * @since 3.0
  888.      */
  889.     public static float clamp(final float value, final float inf, final float sup) {
  890.         return max(inf, min(value, sup));
  891.     }

  892.     /** Clamp a value within an interval.
  893.      * <p>
  894.      * This method assumes -0.0 is below +0.0
  895.      * </p>
  896.      * @param value value to clamp
  897.      * @param inf lower bound of the clamping interval
  898.      * @param sup upper bound of the clamping interval
  899.      * @return value clamped within [inf; sup], or value if already within bounds.
  900.      * @since 3.0
  901.      */
  902.     public static double clamp(final double value, final double inf, final double sup) {
  903.         return max(inf, min(value, sup));
  904.     }

  905.     /** Returns a pseudo-random number between 0.0 and 1.0.
  906.      * <p><b>Note:</b> this implementation currently delegates to {@link Math#random}
  907.      * @return a random number between 0.0 and 1.0
  908.      */
  909.     public static double random() {
  910.         return Math.random();
  911.     }

  912.     /**
  913.      * Exponential function.
  914.      *
  915.      * Computes exp(x), function result is nearly rounded.   It will be correctly
  916.      * rounded to the theoretical value for 99.9% of input values, otherwise it will
  917.      * have a 1 ULP error.
  918.      *
  919.      * Method:
  920.      *    Lookup intVal = exp(int(x))
  921.      *    Lookup fracVal = exp(int(x-int(x) / 1024.0) * 1024.0 );
  922.      *    Compute z as the exponential of the remaining bits by a polynomial minus one
  923.      *    exp(x) = intVal * fracVal * (1 + z)
  924.      *
  925.      * Accuracy:
  926.      *    Calculation is done with 63 bits of precision, so result should be correctly
  927.      *    rounded for 99.9% of input values, with less than 1 ULP error otherwise.
  928.      *
  929.      * @param x   a double
  930.      * @return double e<sup>x</sup>
  931.      */
  932.     public static double exp(double x) {
  933.         return exp(x, 0.0, null);
  934.     }

  935.     /**
  936.      * Internal helper method for exponential function.
  937.      * @param x original argument of the exponential function
  938.      * @param extra extra bits of precision on input (To Be Confirmed)
  939.      * @param hiPrec extra bits of precision on output (To Be Confirmed)
  940.      * @return exp(x)
  941.      */
  942.     private static double exp(double x, double extra, double[] hiPrec) {
  943.         double intPartA;
  944.         double intPartB;
  945.         int intVal = (int) x;

  946.         /* Lookup exp(floor(x)).
  947.          * intPartA will have the upper 22 bits, intPartB will have the lower
  948.          * 52 bits.
  949.          */
  950.         if (x < 0.0) {

  951.             // We don't check against intVal here as conversion of large negative double values
  952.             // may be affected by a JIT bug. Subsequent comparisons can safely use intVal
  953.             if (x < -746d) {
  954.                 if (hiPrec != null) {
  955.                     hiPrec[0] = 0.0;
  956.                     hiPrec[1] = 0.0;
  957.                 }
  958.                 return 0.0;
  959.             }

  960.             if (intVal < -709) {
  961.                 /* This will produce a subnormal output */
  962.                 final double result = exp(x+40.19140625, extra, hiPrec) / 285040095144011776.0;
  963.                 if (hiPrec != null) {
  964.                     hiPrec[0] /= 285040095144011776.0;
  965.                     hiPrec[1] /= 285040095144011776.0;
  966.                 }
  967.                 return result;
  968.             }

  969.             if (intVal == -709) {
  970.                 /* exp(1.494140625) is nearly a machine number... */
  971.                 final double result = exp(x+1.494140625, extra, hiPrec) / 4.455505956692756620;
  972.                 if (hiPrec != null) {
  973.                     hiPrec[0] /= 4.455505956692756620;
  974.                     hiPrec[1] /= 4.455505956692756620;
  975.                 }
  976.                 return result;
  977.             }

  978.             intVal--;

  979.         } else {
  980.             if (intVal > 709) {
  981.                 if (hiPrec != null) {
  982.                     hiPrec[0] = Double.POSITIVE_INFINITY;
  983.                     hiPrec[1] = 0.0;
  984.                 }
  985.                 return Double.POSITIVE_INFINITY;
  986.             }

  987.         }

  988.         intPartA = ExpIntTable.EXP_INT_TABLE_A[EXP_INT_TABLE_MAX_INDEX+intVal];
  989.         intPartB = ExpIntTable.EXP_INT_TABLE_B[EXP_INT_TABLE_MAX_INDEX+intVal];

  990.         /* Get the fractional part of x, find the greatest multiple of 2^-10 less than
  991.          * x and look up the exp function of it.
  992.          * fracPartA will have the upper 22 bits, fracPartB the lower 52 bits.
  993.          */
  994.         final int intFrac = (int) ((x - intVal) * 1024.0);
  995.         final double fracPartA = ExpFracTable.EXP_FRAC_TABLE_A[intFrac];
  996.         final double fracPartB = ExpFracTable.EXP_FRAC_TABLE_B[intFrac];

  997.         /* epsilon is the difference in x from the nearest multiple of 2^-10.  It
  998.          * has a value in the range 0 <= epsilon < 2^-10.
  999.          * Do the subtraction from x as the last step to avoid possible loss of precision.
  1000.          */
  1001.         final double epsilon = x - (intVal + intFrac / 1024.0);

  1002.         /* Compute z = exp(epsilon) - 1.0 via a minimax polynomial.  z has
  1003.        full double precision (52 bits).  Since z < 2^-10, we will have
  1004.        62 bits of precision when combined with the constant 1.  This will be
  1005.        used in the last addition below to get proper rounding. */

  1006.         /* Remez generated polynomial.  Converges on the interval [0, 2^-10], error
  1007.        is less than 0.5 ULP */
  1008.         double z = 0.04168701738764507;
  1009.         z = z * epsilon + 0.1666666505023083;
  1010.         z = z * epsilon + 0.5000000000042687;
  1011.         z = z * epsilon + 1.0;
  1012.         z = z * epsilon + -3.940510424527919E-20;

  1013.         /* Compute (intPartA+intPartB) * (fracPartA+fracPartB) by binomial
  1014.        expansion.
  1015.        tempA is exact since intPartA and intPartB only have 22 bits each.
  1016.        tempB will have 52 bits of precision.
  1017.          */
  1018.         double tempA = intPartA * fracPartA;
  1019.         double tempB = intPartA * fracPartB + intPartB * fracPartA + intPartB * fracPartB;

  1020.         /* Compute the result.  (1+z)(tempA+tempB).  Order of operations is
  1021.        important.  For accuracy add by increasing size.  tempA is exact and
  1022.        much larger than the others.  If there are extra bits specified from the
  1023.        pow() function, use them. */
  1024.         final double tempC = tempB + tempA;

  1025.         // If tempC is positive infinite, the evaluation below could result in NaN,
  1026.         // because z could be negative at the same time.
  1027.         if (tempC == Double.POSITIVE_INFINITY) {
  1028.             if (hiPrec != null) {
  1029.                 hiPrec[0] = Double.POSITIVE_INFINITY;
  1030.                 hiPrec[1] = 0.0;
  1031.             }
  1032.             return Double.POSITIVE_INFINITY;
  1033.         }

  1034.         final double result;
  1035.         if (extra != 0.0) {
  1036.             result = tempC*extra*z + tempC*extra + tempC*z + tempB + tempA;
  1037.         } else {
  1038.             result = tempC*z + tempB + tempA;
  1039.         }

  1040.         if (hiPrec != null) {
  1041.             // If requesting high precision
  1042.             hiPrec[0] = tempA;
  1043.             hiPrec[1] = tempC*extra*z + tempC*extra + tempC*z + tempB;
  1044.         }

  1045.         return result;
  1046.     }

  1047.     /** Compute exp(x) - 1
  1048.      * @param x number to compute shifted exponential
  1049.      * @return exp(x) - 1
  1050.      */
  1051.     public static double expm1(double x) {
  1052.       return expm1(x, null);
  1053.     }

  1054.     /** Internal helper method for expm1
  1055.      * @param x number to compute shifted exponential
  1056.      * @param hiPrecOut receive high precision result for -1.0 < x < 1.0
  1057.      * @return exp(x) - 1
  1058.      */
  1059.     private static double expm1(double x, double[] hiPrecOut) {
  1060.         if (Double.isNaN(x) || x == 0.0) { // NaN or zero
  1061.             return x;
  1062.         }

  1063.         if (x <= -1.0 || x >= 1.0) {
  1064.             // If not between +/- 1.0
  1065.             //return exp(x) - 1.0;
  1066.             double[] hiPrec = new double[2];
  1067.             exp(x, 0.0, hiPrec);
  1068.             if (x > 0.0) {
  1069.                 return -1.0 + hiPrec[0] + hiPrec[1];
  1070.             } else {
  1071.                 final double ra = -1.0 + hiPrec[0];
  1072.                 double rb = -(ra + 1.0 - hiPrec[0]);
  1073.                 rb += hiPrec[1];
  1074.                 return ra + rb;
  1075.             }
  1076.         }

  1077.         double baseA;
  1078.         double baseB;
  1079.         double epsilon;
  1080.         boolean negative = false;

  1081.         if (x < 0.0) {
  1082.             x = -x;
  1083.             negative = true;
  1084.         }

  1085.         {
  1086.             int intFrac = (int) (x * 1024.0);
  1087.             double tempA = ExpFracTable.EXP_FRAC_TABLE_A[intFrac] - 1.0;
  1088.             double tempB = ExpFracTable.EXP_FRAC_TABLE_B[intFrac];

  1089.             double temp = tempA + tempB;
  1090.             tempB = -(temp - tempA - tempB);
  1091.             tempA = temp;

  1092.             temp = tempA * HEX_40000000;
  1093.             baseA = tempA + temp - temp;
  1094.             baseB = tempB + (tempA - baseA);

  1095.             epsilon = x - intFrac/1024.0;
  1096.         }


  1097.         /* Compute expm1(epsilon) */
  1098.         double zb = 0.008336750013465571;
  1099.         zb = zb * epsilon + 0.041666663879186654;
  1100.         zb = zb * epsilon + 0.16666666666745392;
  1101.         zb = zb * epsilon + 0.49999999999999994;
  1102.         zb *= epsilon;
  1103.         zb *= epsilon;

  1104.         double za = epsilon;
  1105.         double temp = za + zb;
  1106.         zb = -(temp - za - zb);
  1107.         za = temp;

  1108.         temp = za * HEX_40000000;
  1109.         temp = za + temp - temp;
  1110.         zb += za - temp;
  1111.         za = temp;

  1112.         /* Combine the parts.   expm1(a+b) = expm1(a) + expm1(b) + expm1(a)*expm1(b) */
  1113.         double ya = za * baseA;
  1114.         //double yb = za*baseB + zb*baseA + zb*baseB;
  1115.         temp = ya + za * baseB;
  1116.         double yb = -(temp - ya - za * baseB);
  1117.         ya = temp;

  1118.         temp = ya + zb * baseA;
  1119.         yb += -(temp - ya - zb * baseA);
  1120.         ya = temp;

  1121.         temp = ya + zb * baseB;
  1122.         yb += -(temp - ya - zb*baseB);
  1123.         ya = temp;

  1124.         //ya = ya + za + baseA;
  1125.         //yb = yb + zb + baseB;
  1126.         temp = ya + baseA;
  1127.         yb += -(temp - baseA - ya);
  1128.         ya = temp;

  1129.         temp = ya + za;
  1130.         //yb += (ya > za) ? -(temp - ya - za) : -(temp - za - ya);
  1131.         yb += -(temp - ya - za);
  1132.         ya = temp;

  1133.         temp = ya + baseB;
  1134.         //yb += (ya > baseB) ? -(temp - ya - baseB) : -(temp - baseB - ya);
  1135.         yb += -(temp - ya - baseB);
  1136.         ya = temp;

  1137.         temp = ya + zb;
  1138.         //yb += (ya > zb) ? -(temp - ya - zb) : -(temp - zb - ya);
  1139.         yb += -(temp - ya - zb);
  1140.         ya = temp;

  1141.         if (negative) {
  1142.             /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */
  1143.             double denom = 1.0 + ya;
  1144.             double denomr = 1.0 / denom;
  1145.             double denomb = -(denom - 1.0 - ya) + yb;
  1146.             double ratio = ya * denomr;
  1147.             temp = ratio * HEX_40000000;
  1148.             final double ra = ratio + temp - temp;
  1149.             double rb = ratio - ra;

  1150.             temp = denom * HEX_40000000;
  1151.             za = denom + temp - temp;
  1152.             zb = denom - za;

  1153.             rb += (ya - za * ra - za * rb - zb * ra - zb * rb) * denomr;

  1154.             // f(x) = x/1+x
  1155.             // Compute f'(x)
  1156.             // Product rule:  d(uv) = du*v + u*dv
  1157.             // Chain rule:  d(f(g(x)) = f'(g(x))*f(g'(x))
  1158.             // d(1/x) = -1/(x*x)
  1159.             // d(1/1+x) = -1/( (1+x)^2) *  1 =  -1/((1+x)*(1+x))
  1160.             // d(x/1+x) = -x/((1+x)(1+x)) + 1/1+x = 1 / ((1+x)(1+x))

  1161.             // Adjust for yb
  1162.             rb += yb * denomr;                      // numerator
  1163.             rb += -ya * denomb * denomr * denomr;   // denominator

  1164.             // negate
  1165.             ya = -ra;
  1166.             yb = -rb;
  1167.         }

  1168.         if (hiPrecOut != null) {
  1169.             hiPrecOut[0] = ya;
  1170.             hiPrecOut[1] = yb;
  1171.         }

  1172.         return ya + yb;
  1173.     }

  1174.     /**
  1175.      * Natural logarithm.
  1176.      *
  1177.      * @param x   a double
  1178.      * @return log(x)
  1179.      */
  1180.     public static double log(final double x) {
  1181.         return log(x, null);
  1182.     }

  1183.     /**
  1184.      * Internal helper method for natural logarithm function.
  1185.      * @param x original argument of the natural logarithm function
  1186.      * @param hiPrec extra bits of precision on output (To Be Confirmed)
  1187.      * @return log(x)
  1188.      */
  1189.     private static double log(final double x, final double[] hiPrec) {
  1190.         if (x==0) { // Handle special case of +0/-0
  1191.             return Double.NEGATIVE_INFINITY;
  1192.         }
  1193.         long bits = Double.doubleToRawLongBits(x);

  1194.         /* Handle special cases of negative input, and NaN */
  1195.         if (((bits & 0x8000000000000000L) != 0 || Double.isNaN(x)) && x != 0.0) {
  1196.             if (hiPrec != null) {
  1197.                 hiPrec[0] = Double.NaN;
  1198.             }

  1199.             return Double.NaN;
  1200.         }

  1201.         /* Handle special cases of Positive infinity. */
  1202.         if (x == Double.POSITIVE_INFINITY) {
  1203.             if (hiPrec != null) {
  1204.                 hiPrec[0] = Double.POSITIVE_INFINITY;
  1205.             }

  1206.             return Double.POSITIVE_INFINITY;
  1207.         }

  1208.         /* Extract the exponent */
  1209.         int exp = (int)(bits >> 52)-1023;

  1210.         if ((bits & 0x7ff0000000000000L) == 0) {
  1211.             // Subnormal!
  1212.             if (x == 0) {
  1213.                 // Zero
  1214.                 if (hiPrec != null) {
  1215.                     hiPrec[0] = Double.NEGATIVE_INFINITY;
  1216.                 }

  1217.                 return Double.NEGATIVE_INFINITY;
  1218.             }

  1219.             /* Normalize the subnormal number. */
  1220.             bits <<= 1;
  1221.             while ( (bits & 0x0010000000000000L) == 0) {
  1222.                 --exp;
  1223.                 bits <<= 1;
  1224.             }
  1225.         }


  1226.         if ((exp == -1 || exp == 0) && x < 1.01 && x > 0.99 && hiPrec == null) {
  1227.             /* The normal method doesn't work well in the range [0.99, 1.01], so call do a straight
  1228.            polynomial expansion in higer precision. */

  1229.             /* Compute x - 1.0 and split it */
  1230.             double xa = x - 1.0;
  1231.             double tmp = xa * HEX_40000000;
  1232.             double aa = xa + tmp - tmp;
  1233.             double ab = xa - aa;
  1234.             xa = aa;
  1235.             double xb = ab;

  1236.             final double[] lnCoef_last = LN_QUICK_COEF[LN_QUICK_COEF.length - 1];
  1237.             double ya = lnCoef_last[0];
  1238.             double yb = lnCoef_last[1];

  1239.             for (int i = LN_QUICK_COEF.length - 2; i >= 0; i--) {
  1240.                 /* Multiply a = y * x */
  1241.                 aa = ya * xa;
  1242.                 ab = ya * xb + yb * xa + yb * xb;
  1243.                 /* split, so now y = a */
  1244.                 tmp = aa * HEX_40000000;
  1245.                 ya = aa + tmp - tmp;
  1246.                 yb = aa - ya + ab;

  1247.                 /* Add  a = y + lnQuickCoef */
  1248.                 final double[] lnCoef_i = LN_QUICK_COEF[i];
  1249.                 aa = ya + lnCoef_i[0];
  1250.                 ab = yb + lnCoef_i[1];
  1251.                 /* Split y = a */
  1252.                 tmp = aa * HEX_40000000;
  1253.                 ya = aa + tmp - tmp;
  1254.                 yb = aa - ya + ab;
  1255.             }

  1256.             /* Multiply a = y * x */
  1257.             aa = ya * xa;
  1258.             ab = ya * xb + yb * xa + yb * xb;
  1259.             /* split, so now y = a */
  1260.             tmp = aa * HEX_40000000;
  1261.             ya = aa + tmp - tmp;
  1262.             yb = aa - ya + ab;

  1263.             return ya + yb;
  1264.         }

  1265.         // lnm is a log of a number in the range of 1.0 - 2.0, so 0 <= lnm < ln(2)
  1266.         final double[] lnm = lnMant.LN_MANT[(int)((bits & 0x000ffc0000000000L) >> 42)];

  1267.         /*
  1268.     double epsilon = x / Double.longBitsToDouble(bits & 0xfffffc0000000000L);

  1269.     epsilon -= 1.0;
  1270.          */

  1271.         // y is the most significant 10 bits of the mantissa
  1272.         //double y = Double.longBitsToDouble(bits & 0xfffffc0000000000L);
  1273.         //double epsilon = (x - y) / y;
  1274.         final double epsilon = (bits & 0x3ffffffffffL) / (TWO_POWER_52 + (bits & 0x000ffc0000000000L));

  1275.         double lnza;
  1276.         double lnzb = 0.0;

  1277.         if (hiPrec != null) {
  1278.             /* split epsilon -> x */
  1279.             double tmp = epsilon * HEX_40000000;
  1280.             double aa = epsilon + tmp - tmp;
  1281.             double ab = epsilon - aa;
  1282.             double xa = aa;
  1283.             double xb = ab;

  1284.             /* Need a more accurate epsilon, so adjust the division. */
  1285.             final double numer = bits & 0x3ffffffffffL;
  1286.             final double denom = TWO_POWER_52 + (bits & 0x000ffc0000000000L);
  1287.             aa = numer - xa*denom - xb * denom;
  1288.             xb += aa / denom;

  1289.             /* Remez polynomial evaluation */
  1290.             final double[] lnCoef_last = LN_HI_PREC_COEF[LN_HI_PREC_COEF.length-1];
  1291.             double ya = lnCoef_last[0];
  1292.             double yb = lnCoef_last[1];

  1293.             for (int i = LN_HI_PREC_COEF.length - 2; i >= 0; i--) {
  1294.                 /* Multiply a = y * x */
  1295.                 aa = ya * xa;
  1296.                 ab = ya * xb + yb * xa + yb * xb;
  1297.                 /* split, so now y = a */
  1298.                 tmp = aa * HEX_40000000;
  1299.                 ya = aa + tmp - tmp;
  1300.                 yb = aa - ya + ab;

  1301.                 /* Add  a = y + lnHiPrecCoef */
  1302.                 final double[] lnCoef_i = LN_HI_PREC_COEF[i];
  1303.                 aa = ya + lnCoef_i[0];
  1304.                 ab = yb + lnCoef_i[1];
  1305.                 /* Split y = a */
  1306.                 tmp = aa * HEX_40000000;
  1307.                 ya = aa + tmp - tmp;
  1308.                 yb = aa - ya + ab;
  1309.             }

  1310.             /* Multiply a = y * x */
  1311.             aa = ya * xa;
  1312.             ab = ya * xb + yb * xa + yb * xb;

  1313.             /* split, so now lnz = a */
  1314.             /*
  1315.       tmp = aa * 1073741824.0;
  1316.       lnza = aa + tmp - tmp;
  1317.       lnzb = aa - lnza + ab;
  1318.              */
  1319.             lnza = aa + ab;
  1320.             lnzb = -(lnza - aa - ab);
  1321.         } else {
  1322.             /* High precision not required.  Eval Remez polynomial
  1323.          using standard double precision */
  1324.             lnza = -0.16624882440418567;
  1325.             lnza = lnza * epsilon + 0.19999954120254515;
  1326.             lnza = lnza * epsilon + -0.2499999997677497;
  1327.             lnza = lnza * epsilon + 0.3333333333332802;
  1328.             lnza = lnza * epsilon + -0.5;
  1329.             lnza = lnza * epsilon + 1.0;
  1330.             lnza *= epsilon;
  1331.         }

  1332.         /* Relative sizes:
  1333.          * lnzb     [0, 2.33E-10]
  1334.          * lnm[1]   [0, 1.17E-7]
  1335.          * ln2B*exp [0, 1.12E-4]
  1336.          * lnza      [0, 9.7E-4]
  1337.          * lnm[0]   [0, 0.692]
  1338.          * ln2A*exp [0, 709]
  1339.          */

  1340.         /* Compute the following sum:
  1341.          * lnzb + lnm[1] + ln2B*exp + lnza + lnm[0] + ln2A*exp;
  1342.          */

  1343.         //return lnzb + lnm[1] + ln2B*exp + lnza + lnm[0] + ln2A*exp;
  1344.         double a = LN_2_A*exp;
  1345.         double b = 0.0;
  1346.         double c = a+lnm[0];
  1347.         double d = -(c-a-lnm[0]);
  1348.         a = c;
  1349.         b += d;

  1350.         c = a + lnza;
  1351.         d = -(c - a - lnza);
  1352.         a = c;
  1353.         b += d;

  1354.         c = a + LN_2_B*exp;
  1355.         d = -(c - a - LN_2_B*exp);
  1356.         a = c;
  1357.         b += d;

  1358.         c = a + lnm[1];
  1359.         d = -(c - a - lnm[1]);
  1360.         a = c;
  1361.         b += d;

  1362.         c = a + lnzb;
  1363.         d = -(c - a - lnzb);
  1364.         a = c;
  1365.         b += d;

  1366.         if (hiPrec != null) {
  1367.             hiPrec[0] = a;
  1368.             hiPrec[1] = b;
  1369.         }

  1370.         return a + b;
  1371.     }

  1372.     /**
  1373.      * Computes log(1 + x).
  1374.      *
  1375.      * @param x Number.
  1376.      * @return {@code log(1 + x)}.
  1377.      */
  1378.     public static double log1p(final double x) {
  1379.         if (x == -1) {
  1380.             return Double.NEGATIVE_INFINITY;
  1381.         }

  1382.         if (x == Double.POSITIVE_INFINITY) {
  1383.             return Double.POSITIVE_INFINITY;
  1384.         }

  1385.         if (x > 1e-6 ||
  1386.             x < -1e-6) {
  1387.             final double xpa = 1 + x;
  1388.             final double xpb = -(xpa - 1 - x);

  1389.             final double[] hiPrec = new double[2];
  1390.             final double lores = log(xpa, hiPrec);
  1391.             if (Double.isInfinite(lores)) { // Don't allow this to be converted to NaN
  1392.                 return lores;
  1393.             }

  1394.             // Do a taylor series expansion around xpa:
  1395.             //   f(x+y) = f(x) + f'(x) y + f''(x)/2 y^2
  1396.             final double fx1 = xpb / xpa;
  1397.             final double epsilon = 0.5 * fx1 + 1;
  1398.             return epsilon * fx1 + hiPrec[1] + hiPrec[0];
  1399.         } else {
  1400.             // Value is small |x| < 1e6, do a Taylor series centered on 1.
  1401.             final double y = (x * F_1_3 - F_1_2) * x + 1;
  1402.             return y * x;
  1403.         }
  1404.     }

  1405.     /** Compute the base 10 logarithm.
  1406.      * @param x a number
  1407.      * @return log10(x)
  1408.      */
  1409.     public static double log10(final double x) {
  1410.         final double[] hiPrec = new double[2];

  1411.         final double lores = log(x, hiPrec);
  1412.         if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN
  1413.             return lores;
  1414.         }

  1415.         final double tmp = hiPrec[0] * HEX_40000000;
  1416.         final double lna = hiPrec[0] + tmp - tmp;
  1417.         final double lnb = hiPrec[0] - lna + hiPrec[1];

  1418.         final double rln10a = 0.4342944622039795;
  1419.         final double rln10b = 1.9699272335463627E-8;

  1420.         return rln10b * lnb + rln10b * lna + rln10a * lnb + rln10a * lna;
  1421.     }

  1422.     /**
  1423.      * Computes the <a href="http://mathworld.wolfram.com/Logarithm.html">
  1424.      * logarithm</a> in a given base.
  1425.      *
  1426.      * Returns {@code NaN} if either argument is negative.
  1427.      * If {@code base} is 0 and {@code x} is positive, 0 is returned.
  1428.      * If {@code base} is positive and {@code x} is 0,
  1429.      * {@code Double.NEGATIVE_INFINITY} is returned.
  1430.      * If both arguments are 0, the result is {@code NaN}.
  1431.      *
  1432.      * @param base Base of the logarithm, must be greater than 0.
  1433.      * @param x Argument, must be greater than 0.
  1434.      * @return the value of the logarithm, i.e. the number {@code y} such that
  1435.      * <code>base<sup>y</sup> = x</code>.
  1436.      */
  1437.     public static double log(double base, double x) {
  1438.         return log(x) / log(base);
  1439.     }

  1440.     /**
  1441.      * Power function.  Compute x^y.
  1442.      *
  1443.      * @param x   a double
  1444.      * @param y   a double
  1445.      * @return double
  1446.      */
  1447.     public static double pow(final double x, final double y) {

  1448.         if (y == 0) {
  1449.             // y = -0 or y = +0
  1450.             return 1.0;
  1451.         } else {

  1452.             final long yBits        = Double.doubleToRawLongBits(y);
  1453.             final int  yRawExp      = (int) ((yBits & MASK_DOUBLE_EXPONENT) >> 52);
  1454.             final long yRawMantissa = yBits & MASK_DOUBLE_MANTISSA;
  1455.             final long xBits        = Double.doubleToRawLongBits(x);
  1456.             final int  xRawExp      = (int) ((xBits & MASK_DOUBLE_EXPONENT) >> 52);
  1457.             final long xRawMantissa = xBits & MASK_DOUBLE_MANTISSA;

  1458.             if (yRawExp > 1085) {
  1459.                 // y is either a very large integral value that does not fit in a long or it is a special number

  1460.                 if ((yRawExp == 2047 && yRawMantissa != 0) ||
  1461.                     (xRawExp == 2047 && xRawMantissa != 0)) {
  1462.                     // NaN
  1463.                     return Double.NaN;
  1464.                 } else if (xRawExp == 1023 && xRawMantissa == 0) {
  1465.                     // x = -1.0 or x = +1.0
  1466.                     if (yRawExp == 2047) {
  1467.                         // y is infinite
  1468.                         return Double.NaN;
  1469.                     } else {
  1470.                         // y is a large even integer
  1471.                         return 1.0;
  1472.                     }
  1473.                 } else {
  1474.                     // the absolute value of x is either greater or smaller than 1.0

  1475.                     // if yRawExp == 2047 and mantissa is 0, y = -infinity or y = +infinity
  1476.                     // if 1085 < yRawExp < 2047, y is simply a large number, however, due to limited
  1477.                     // accuracy, at this magnitude it behaves just like infinity with regards to x
  1478.                     if ((y > 0) ^ (xRawExp < 1023)) {
  1479.                         // either y = +infinity (or large engouh) and abs(x) > 1.0
  1480.                         // or     y = -infinity (or large engouh) and abs(x) < 1.0
  1481.                         return Double.POSITIVE_INFINITY;
  1482.                     } else {
  1483.                         // either y = +infinity (or large engouh) and abs(x) < 1.0
  1484.                         // or     y = -infinity (or large engouh) and abs(x) > 1.0
  1485.                         return +0.0;
  1486.                     }
  1487.                 }

  1488.             } else {
  1489.                 // y is a regular non-zero number

  1490.                 if (yRawExp >= 1023) {
  1491.                     // y may be an integral value, which should be handled specifically
  1492.                     final long yFullMantissa = IMPLICIT_HIGH_BIT | yRawMantissa;
  1493.                     if (yRawExp < 1075) {
  1494.                         // normal number with negative shift that may have a fractional part
  1495.                         final long integralMask = (-1L) << (1075 - yRawExp);
  1496.                         if ((yFullMantissa & integralMask) == yFullMantissa) {
  1497.                             // all fractional bits are 0, the number is really integral
  1498.                             final long l = yFullMantissa >> (1075 - yRawExp);
  1499.                             return pow(x, (y < 0) ? -l : l);
  1500.                         }
  1501.                     } else {
  1502.                         // normal number with positive shift, always an integral value
  1503.                         // we know it fits in a primitive long because yRawExp > 1085 has been handled above
  1504.                         final long l =  yFullMantissa << (yRawExp - 1075);
  1505.                         return pow(x, (y < 0) ? -l : l);
  1506.                     }
  1507.                 }

  1508.                 // y is a non-integral value

  1509.                 if (x == 0) {
  1510.                     // x = -0 or x = +0
  1511.                     // the integer powers have already been handled above
  1512.                     return y < 0 ? Double.POSITIVE_INFINITY : +0.0;
  1513.                 } else if (xRawExp == 2047) {
  1514.                     if (xRawMantissa == 0) {
  1515.                         // x = -infinity or x = +infinity
  1516.                         return (y < 0) ? +0.0 : Double.POSITIVE_INFINITY;
  1517.                     } else {
  1518.                         // NaN
  1519.                         return Double.NaN;
  1520.                     }
  1521.                 } else if (x < 0) {
  1522.                     // the integer powers have already been handled above
  1523.                     return Double.NaN;
  1524.                 } else {

  1525.                     // this is the general case, for regular fractional numbers x and y

  1526.                     // Split y into ya and yb such that y = ya+yb
  1527.                     final double tmp = y * HEX_40000000;
  1528.                     final double ya = (y + tmp) - tmp;
  1529.                     final double yb = y - ya;

  1530.                     /* Compute ln(x) */
  1531.                     final double[] lns = new double[2];
  1532.                     final double lores = log(x, lns);
  1533.                     if (Double.isInfinite(lores)) { // don't allow this to be converted to NaN
  1534.                         return lores;
  1535.                     }

  1536.                     double lna = lns[0];
  1537.                     double lnb = lns[1];

  1538.                     /* resplit lns */
  1539.                     final double tmp1 = lna * HEX_40000000;
  1540.                     final double tmp2 = (lna + tmp1) - tmp1;
  1541.                     lnb += lna - tmp2;
  1542.                     lna = tmp2;

  1543.                     // y*ln(x) = (aa+ab)
  1544.                     final double aa = lna * ya;
  1545.                     final double ab = lna * yb + lnb * ya + lnb * yb;

  1546.                     lna = aa+ab;
  1547.                     lnb = -(lna - aa - ab);

  1548.                     double z = 1.0 / 120.0;
  1549.                     z = z * lnb + (1.0 / 24.0);
  1550.                     z = z * lnb + (1.0 / 6.0);
  1551.                     z = z * lnb + 0.5;
  1552.                     z = z * lnb + 1.0;
  1553.                     z *= lnb;

  1554.                     return exp(lna, z, null);

  1555.                 }
  1556.             }

  1557.         }

  1558.     }

  1559.     /**
  1560.      * Raise a double to an int power.
  1561.      *
  1562.      * @param d Number to raise.
  1563.      * @param e Exponent.
  1564.      * @return d<sup>e</sup>
  1565.      */
  1566.     public static double pow(double d, int e) {
  1567.         return pow(d, (long) e);
  1568.     }

  1569.     /**
  1570.      * Raise a double to a long power.
  1571.      *
  1572.      * @param d Number to raise.
  1573.      * @param e Exponent.
  1574.      * @return d<sup>e</sup>
  1575.      */
  1576.     public static double pow(double d, long e) {
  1577.         if (e == 0) {
  1578.             return 1.0;
  1579.         } else if (e > 0) {
  1580.             return new Split(d).pow(e).full;
  1581.         } else {
  1582.             return new Split(d).reciprocal().pow(-e).full;
  1583.         }
  1584.     }

  1585.     /** Class operator on double numbers split into one 26 bits number and one 27 bits number. */
  1586.     private static class Split {

  1587.         /** Split version of NaN. */
  1588.         public static final Split NAN = new Split(Double.NaN, 0);

  1589.         /** Split version of positive infinity. */
  1590.         public static final Split POSITIVE_INFINITY = new Split(Double.POSITIVE_INFINITY, 0);

  1591.         /** Split version of negative infinity. */
  1592.         public static final Split NEGATIVE_INFINITY = new Split(Double.NEGATIVE_INFINITY, 0);

  1593.         /** Full number. */
  1594.         private final double full;

  1595.         /** High order bits. */
  1596.         private final double high;

  1597.         /** Low order bits. */
  1598.         private final double low;

  1599.         /** Simple constructor.
  1600.          * @param x number to split
  1601.          */
  1602.         Split(final double x) {
  1603.             full = x;
  1604.             high = Double.longBitsToDouble(Double.doubleToRawLongBits(x) & ((-1L) << 27));
  1605.             low  = x - high;
  1606.         }

  1607.         /** Simple constructor.
  1608.          * @param high high order bits
  1609.          * @param low low order bits
  1610.          */
  1611.         Split(final double high, final double low) {
  1612.             this(high == 0.0 ? (low == 0.0 && Double.doubleToRawLongBits(high) == Long.MIN_VALUE /* negative zero */ ? -0.0 : low) : high + low, high, low);
  1613.         }

  1614.         /** Simple constructor.
  1615.          * @param full full number
  1616.          * @param high high order bits
  1617.          * @param low low order bits
  1618.          */
  1619.         Split(final double full, final double high, final double low) {
  1620.             this.full = full;
  1621.             this.high = high;
  1622.             this.low  = low;
  1623.         }

  1624.         /** Multiply the instance by another one.
  1625.          * @param b other instance to multiply by
  1626.          * @return product
  1627.          */
  1628.         public Split multiply(final Split b) {
  1629.             // beware the following expressions must NOT be simplified, they rely on floating point arithmetic properties
  1630.             final Split  mulBasic  = new Split(full * b.full);
  1631.             final double mulError  = low * b.low - (((mulBasic.full - high * b.high) - low * b.high) - high * b.low);
  1632.             return new Split(mulBasic.high, mulBasic.low + mulError);
  1633.         }

  1634.         /** Compute the reciprocal of the instance.
  1635.          * @return reciprocal of the instance
  1636.          */
  1637.         public Split reciprocal() {

  1638.             final double approximateInv = 1.0 / full;
  1639.             final Split  splitInv       = new Split(approximateInv);

  1640.             // if 1.0/d were computed perfectly, remultiplying it by d should give 1.0
  1641.             // we want to estimate the error so we can fix the low order bits of approximateInvLow
  1642.             // beware the following expressions must NOT be simplified, they rely on floating point arithmetic properties
  1643.             final Split product = multiply(splitInv);
  1644.             final double error  = (product.high - 1) + product.low;

  1645.             // better accuracy estimate of reciprocal
  1646.             return Double.isNaN(error) ? splitInv : new Split(splitInv.high, splitInv.low - error / full);

  1647.         }

  1648.         /** Computes this^e.
  1649.          * @param e exponent (beware, here it MUST be > 0; the only exclusion is Long.MIN_VALUE)
  1650.          * @return d^e, split in high and low bits
  1651.          */
  1652.         private Split pow(final long e) {

  1653.             // prepare result
  1654.             Split result = new Split(1);

  1655.             // d^(2p)
  1656.             Split d2p = new Split(full, high, low);

  1657.             for (long p = e; p != 0; p >>>= 1) {

  1658.                 if ((p & 0x1) != 0) {
  1659.                     // accurate multiplication result = result * d^(2p) using Veltkamp TwoProduct algorithm
  1660.                     result = result.multiply(d2p);
  1661.                 }

  1662.                 // accurate squaring d^(2(p+1)) = d^(2p) * d^(2p) using Veltkamp TwoProduct algorithm
  1663.                 d2p = d2p.multiply(d2p);

  1664.             }

  1665.             if (Double.isNaN(result.full)) {
  1666.                 if (Double.isNaN(full)) {
  1667.                     return NAN;
  1668.                 } else {
  1669.                     // some intermediate numbers exceeded capacity,
  1670.                     // and the low order bits became NaN (because infinity - infinity = NaN)
  1671.                     if (abs(full) < 1) {
  1672.                         return new Split(copySign(0.0, full), 0.0);
  1673.                     } else if (full < 0 && (e & 0x1) == 1) {
  1674.                         return NEGATIVE_INFINITY;
  1675.                     } else {
  1676.                         return POSITIVE_INFINITY;
  1677.                     }
  1678.                 }
  1679.             } else {
  1680.                 return result;
  1681.             }

  1682.         }

  1683.     }

  1684.     /**
  1685.      *  Computes sin(x) - x, where |x| < 1/16.
  1686.      *  Use a Remez polynomial approximation.
  1687.      *  @param x a number smaller than 1/16
  1688.      *  @return sin(x) - x
  1689.      */
  1690.     private static double polySine(final double x)
  1691.     {
  1692.         double x2 = x*x;

  1693.         double p = 2.7553817452272217E-6;
  1694.         p = p * x2 + -1.9841269659586505E-4;
  1695.         p = p * x2 + 0.008333333333329196;
  1696.         p = p * x2 + -0.16666666666666666;
  1697.         //p *= x2;
  1698.         //p *= x;
  1699.         p = p * x2 * x;

  1700.         return p;
  1701.     }

  1702.     /**
  1703.      *  Computes cos(x) - 1, where |x| < 1/16.
  1704.      *  Use a Remez polynomial approximation.
  1705.      *  @param x a number smaller than 1/16
  1706.      *  @return cos(x) - 1
  1707.      */
  1708.     private static double polyCosine(double x) {
  1709.         double x2 = x*x;

  1710.         double p = 2.479773539153719E-5;
  1711.         p = p * x2 + -0.0013888888689039883;
  1712.         p = p * x2 + 0.041666666666621166;
  1713.         p = p * x2 + -0.49999999999999994;
  1714.         p *= x2;

  1715.         return p;
  1716.     }

  1717.     /**
  1718.      *  Compute sine over the first quadrant (0 < x < pi/2).
  1719.      *  Use combination of table lookup and rational polynomial expansion.
  1720.      *  @param xa number from which sine is requested
  1721.      *  @param xb extra bits for x (may be 0.0)
  1722.      *  @return sin(xa + xb)
  1723.      */
  1724.     private static double sinQ(double xa, double xb) {
  1725.         int idx = (int) ((xa * 8.0) + 0.5);
  1726.         final double epsilon = xa - EIGHTHS[idx]; //idx*0.125;

  1727.         // Table lookups
  1728.         final double sintA = SINE_TABLE_A[idx];
  1729.         final double sintB = SINE_TABLE_B[idx];
  1730.         final double costA = COSINE_TABLE_A[idx];
  1731.         final double costB = COSINE_TABLE_B[idx];

  1732.         // Polynomial eval of sin(epsilon), cos(epsilon)
  1733.         double sinEpsA = epsilon;
  1734.         double sinEpsB = polySine(epsilon);
  1735.         final double cosEpsA = 1.0;
  1736.         final double cosEpsB = polyCosine(epsilon);

  1737.         // Split epsilon   xa + xb = x
  1738.         final double temp = sinEpsA * HEX_40000000;
  1739.         double temp2 = (sinEpsA + temp) - temp;
  1740.         sinEpsB +=  sinEpsA - temp2;
  1741.         sinEpsA = temp2;

  1742.         /* Compute sin(x) by angle addition formula */
  1743.         double result;

  1744.         /* Compute the following sum:
  1745.          *
  1746.          * result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB +
  1747.          *          sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;
  1748.          *
  1749.          * Ranges of elements
  1750.          *
  1751.          * xxxtA   0            PI/2
  1752.          * xxxtB   -1.5e-9      1.5e-9
  1753.          * sinEpsA -0.0625      0.0625
  1754.          * sinEpsB -6e-11       6e-11
  1755.          * cosEpsA  1.0
  1756.          * cosEpsB  0           -0.0625
  1757.          *
  1758.          */

  1759.         //result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB +
  1760.         //          sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;

  1761.         //result = sintA + sintA*cosEpsB + sintB + sintB * cosEpsB;
  1762.         //result += costA*sinEpsA + costA*sinEpsB + costB*sinEpsA + costB * sinEpsB;
  1763.         double a = 0;
  1764.         double b = 0;

  1765.         double t = sintA;
  1766.         double c = a + t;
  1767.         double d = -(c - a - t);
  1768.         a = c;
  1769.         b += d;

  1770.         t = costA * sinEpsA;
  1771.         c = a + t;
  1772.         d = -(c - a - t);
  1773.         a = c;
  1774.         b += d;

  1775.         b = b + sintA * cosEpsB + costA * sinEpsB;
  1776.         /*
  1777.     t = sintA*cosEpsB;
  1778.     c = a + t;
  1779.     d = -(c - a - t);
  1780.     a = c;
  1781.     b = b + d;

  1782.     t = costA*sinEpsB;
  1783.     c = a + t;
  1784.     d = -(c - a - t);
  1785.     a = c;
  1786.     b = b + d;
  1787.          */

  1788.         b = b + sintB + costB * sinEpsA + sintB * cosEpsB + costB * sinEpsB;
  1789.         /*
  1790.     t = sintB;
  1791.     c = a + t;
  1792.     d = -(c - a - t);
  1793.     a = c;
  1794.     b = b + d;

  1795.     t = costB*sinEpsA;
  1796.     c = a + t;
  1797.     d = -(c - a - t);
  1798.     a = c;
  1799.     b = b + d;

  1800.     t = sintB*cosEpsB;
  1801.     c = a + t;
  1802.     d = -(c - a - t);
  1803.     a = c;
  1804.     b = b + d;

  1805.     t = costB*sinEpsB;
  1806.     c = a + t;
  1807.     d = -(c - a - t);
  1808.     a = c;
  1809.     b = b + d;
  1810.          */

  1811.         if (xb != 0.0) {
  1812.             t = ((costA + costB) * (cosEpsA + cosEpsB) -
  1813.                  (sintA + sintB) * (sinEpsA + sinEpsB)) * xb;  // approximate cosine*xb
  1814.             c = a + t;
  1815.             d = -(c - a - t);
  1816.             a = c;
  1817.             b += d;
  1818.         }

  1819.         result = a + b;

  1820.         return result;
  1821.     }

  1822.     /**
  1823.      * Compute cosine in the first quadrant by subtracting input from PI/2 and
  1824.      * then calling sinQ.  This is more accurate as the input approaches PI/2.
  1825.      *  @param xa number from which cosine is requested
  1826.      *  @param xb extra bits for x (may be 0.0)
  1827.      *  @return cos(xa + xb)
  1828.      */
  1829.     private static double cosQ(double xa, double xb) {
  1830.         final double pi2a = 1.5707963267948966;
  1831.         final double pi2b = 6.123233995736766E-17;

  1832.         final double a = pi2a - xa;
  1833.         double b = -(a - pi2a + xa);
  1834.         b += pi2b - xb;

  1835.         return sinQ(a, b);
  1836.     }

  1837.     /**
  1838.      *  Compute tangent (or cotangent) over the first quadrant.   0 < x < pi/2
  1839.      *  Use combination of table lookup and rational polynomial expansion.
  1840.      *  @param xa number from which sine is requested
  1841.      *  @param xb extra bits for x (may be 0.0)
  1842.      *  @param cotanFlag if true, compute the cotangent instead of the tangent
  1843.      *  @return tan(xa+xb) (or cotangent, depending on cotanFlag)
  1844.      */
  1845.     private static double tanQ(double xa, double xb, boolean cotanFlag) {

  1846.         int idx = (int) ((xa * 8.0) + 0.5);
  1847.         final double epsilon = xa - EIGHTHS[idx]; //idx*0.125;

  1848.         // Table lookups
  1849.         final double sintA = SINE_TABLE_A[idx];
  1850.         final double sintB = SINE_TABLE_B[idx];
  1851.         final double costA = COSINE_TABLE_A[idx];
  1852.         final double costB = COSINE_TABLE_B[idx];

  1853.         // Polynomial eval of sin(epsilon), cos(epsilon)
  1854.         double sinEpsA = epsilon;
  1855.         double sinEpsB = polySine(epsilon);
  1856.         final double cosEpsA = 1.0;
  1857.         final double cosEpsB = polyCosine(epsilon);

  1858.         // Split epsilon   xa + xb = x
  1859.         double temp = sinEpsA * HEX_40000000;
  1860.         double temp2 = (sinEpsA + temp) - temp;
  1861.         sinEpsB +=  sinEpsA - temp2;
  1862.         sinEpsA = temp2;

  1863.         /* Compute sin(x) by angle addition formula */

  1864.         /* Compute the following sum:
  1865.          *
  1866.          * result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB +
  1867.          *          sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;
  1868.          *
  1869.          * Ranges of elements
  1870.          *
  1871.          * xxxtA   0            PI/2
  1872.          * xxxtB   -1.5e-9      1.5e-9
  1873.          * sinEpsA -0.0625      0.0625
  1874.          * sinEpsB -6e-11       6e-11
  1875.          * cosEpsA  1.0
  1876.          * cosEpsB  0           -0.0625
  1877.          *
  1878.          */

  1879.         //result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB +
  1880.         //          sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;

  1881.         //result = sintA + sintA*cosEpsB + sintB + sintB * cosEpsB;
  1882.         //result += costA*sinEpsA + costA*sinEpsB + costB*sinEpsA + costB * sinEpsB;
  1883.         double a = 0;
  1884.         double b = 0;

  1885.         // Compute sine
  1886.         double t = sintA;
  1887.         double c = a + t;
  1888.         double d = -(c - a - t);
  1889.         a = c;
  1890.         b += d;

  1891.         t = costA*sinEpsA;
  1892.         c = a + t;
  1893.         d = -(c - a - t);
  1894.         a = c;
  1895.         b += d;

  1896.         b += sintA*cosEpsB + costA*sinEpsB;
  1897.         b += sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;

  1898.         double sina = a + b;
  1899.         double sinb = -(sina - a - b);

  1900.         // Compute cosine

  1901.         a = 0.0;
  1902.         b = 0.0;

  1903.         t = costA*cosEpsA;
  1904.         c = a + t;
  1905.         d = -(c - a - t);
  1906.         a = c;
  1907.         b += d;

  1908.         t = -sintA*sinEpsA;
  1909.         c = a + t;
  1910.         d = -(c - a - t);
  1911.         a = c;
  1912.         b += d;

  1913.         b += costB*cosEpsA + costA*cosEpsB + costB*cosEpsB;
  1914.         b -= sintB*sinEpsA + sintA*sinEpsB + sintB*sinEpsB;

  1915.         double cosa = a + b;
  1916.         double cosb = -(cosa - a - b);

  1917.         if (cotanFlag) {
  1918.             double tmp;
  1919.             tmp = cosa; cosa = sina; sina = tmp;
  1920.             tmp = cosb; cosb = sinb; sinb = tmp;
  1921.         }


  1922.         /* estimate and correct, compute 1.0/(cosa+cosb) */
  1923.         /*
  1924.     double est = (sina+sinb)/(cosa+cosb);
  1925.     double err = (sina - cosa*est) + (sinb - cosb*est);
  1926.     est += err/(cosa+cosb);
  1927.     err = (sina - cosa*est) + (sinb - cosb*est);
  1928.          */

  1929.         // f(x) = 1/x,   f'(x) = -1/x^2

  1930.         double est = sina/cosa;

  1931.         /* Split the estimate to get more accurate read on division rounding */
  1932.         temp = est * HEX_40000000;
  1933.         double esta = (est + temp) - temp;
  1934.         double estb =  est - esta;

  1935.         temp = cosa * HEX_40000000;
  1936.         double cosaa = (cosa + temp) - temp;
  1937.         double cosab =  cosa - cosaa;

  1938.         //double err = (sina - est*cosa)/cosa;  // Correction for division rounding
  1939.         double err = (sina - esta*cosaa - esta*cosab - estb*cosaa - estb*cosab)/cosa;  // Correction for division rounding
  1940.         err += sinb/cosa;                     // Change in est due to sinb
  1941.         err += -sina * cosb / cosa / cosa;    // Change in est due to cosb

  1942.         if (xb != 0.0) {
  1943.             // tan' = 1 + tan^2      cot' = -(1 + cot^2)
  1944.             // Approximate impact of xb
  1945.             double xbadj = xb + est*est*xb;
  1946.             if (cotanFlag) {
  1947.                 xbadj = -xbadj;
  1948.             }

  1949.             err += xbadj;
  1950.         }

  1951.         return est+err;
  1952.     }

  1953.     /** Reduce the input argument using the Payne and Hanek method.
  1954.      *  This is good for all inputs 0.0 < x < inf
  1955.      *  Output is remainder after dividing by PI/2
  1956.      *  The result array should contain 3 numbers.
  1957.      *  result[0] is the integer portion, so mod 4 this gives the quadrant.
  1958.      *  result[1] is the upper bits of the remainder
  1959.      *  result[2] is the lower bits of the remainder
  1960.      *
  1961.      * @param x number to reduce
  1962.      * @param result placeholder where to put the result
  1963.      */
  1964.     private static void reducePayneHanek(double x, double[] result)
  1965.     {
  1966.         /* Convert input double to bits */
  1967.         long inbits = Double.doubleToRawLongBits(x);
  1968.         int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;

  1969.         /* Convert to fixed point representation */
  1970.         inbits &= 0x000fffffffffffffL;
  1971.         inbits |= 0x0010000000000000L;

  1972.         /* Normalize input to be between 0.5 and 1.0 */
  1973.         exponent++;
  1974.         inbits <<= 11;

  1975.         /* Based on the exponent, get a shifted copy of recip2pi */
  1976.         long shpi0;
  1977.         long shpiA;
  1978.         long shpiB;
  1979.         int idx = exponent >> 6;
  1980.         int shift = exponent - (idx << 6);

  1981.         if (shift != 0) {
  1982.             shpi0 = (idx == 0) ? 0 : (RECIP_2PI[idx-1] << shift);
  1983.             shpi0 |= RECIP_2PI[idx] >>> (64-shift);
  1984.             shpiA = (RECIP_2PI[idx] << shift) | (RECIP_2PI[idx+1] >>> (64-shift));
  1985.             shpiB = (RECIP_2PI[idx+1] << shift) | (RECIP_2PI[idx+2] >>> (64-shift));
  1986.         } else {
  1987.             shpi0 = (idx == 0) ? 0 : RECIP_2PI[idx-1];
  1988.             shpiA = RECIP_2PI[idx];
  1989.             shpiB = RECIP_2PI[idx+1];
  1990.         }

  1991.         /* Multiply input by shpiA */
  1992.         long a = inbits >>> 32;
  1993.         long b = inbits & 0xffffffffL;

  1994.         long c = shpiA >>> 32;
  1995.         long d = shpiA & 0xffffffffL;

  1996.         long ac = a * c;
  1997.         long bd = b * d;
  1998.         long bc = b * c;
  1999.         long ad = a * d;

  2000.         long prodB = bd + (ad << 32);
  2001.         long prodA = ac + (ad >>> 32);

  2002.         boolean bita = (bd & 0x8000000000000000L) != 0;
  2003.         boolean bitb = (ad & 0x80000000L ) != 0;
  2004.         boolean bitsum = (prodB & 0x8000000000000000L) != 0;

  2005.         /* Carry */
  2006.         if ( (bita && bitb) ||
  2007.                 ((bita || bitb) && !bitsum) ) {
  2008.             prodA++;
  2009.         }

  2010.         bita = (prodB & 0x8000000000000000L) != 0;
  2011.         bitb = (bc & 0x80000000L ) != 0;

  2012.         prodB += bc << 32;
  2013.         prodA += bc >>> 32;

  2014.         bitsum = (prodB & 0x8000000000000000L) != 0;

  2015.         /* Carry */
  2016.         if ( (bita && bitb) ||
  2017.                 ((bita || bitb) && !bitsum) ) {
  2018.             prodA++;
  2019.         }

  2020.         /* Multiply input by shpiB */
  2021.         c = shpiB >>> 32;
  2022.         d = shpiB & 0xffffffffL;
  2023.         ac = a * c;
  2024.         bc = b * c;
  2025.         ad = a * d;

  2026.         /* Collect terms */
  2027.         ac += (bc + ad) >>> 32;

  2028.         bita = (prodB & 0x8000000000000000L) != 0;
  2029.         bitb = (ac & 0x8000000000000000L ) != 0;
  2030.         prodB += ac;
  2031.         bitsum = (prodB & 0x8000000000000000L) != 0;
  2032.         /* Carry */
  2033.         if ( (bita && bitb) ||
  2034.                 ((bita || bitb) && !bitsum) ) {
  2035.             prodA++;
  2036.         }

  2037.         /* Multiply by shpi0 */
  2038.         c = shpi0 >>> 32;
  2039.         d = shpi0 & 0xffffffffL;

  2040.         bd = b * d;
  2041.         bc = b * c;
  2042.         ad = a * d;

  2043.         prodA += bd + ((bc + ad) << 32);

  2044.         /*
  2045.          * prodA, prodB now contain the remainder as a fraction of PI.  We want this as a fraction of
  2046.          * PI/2, so use the following steps:
  2047.          * 1.) multiply by 4.
  2048.          * 2.) do a fixed point muliply by PI/4.
  2049.          * 3.) Convert to floating point.
  2050.          * 4.) Multiply by 2
  2051.          */

  2052.         /* This identifies the quadrant */
  2053.         int intPart = (int)(prodA >>> 62);

  2054.         /* Multiply by 4 */
  2055.         prodA <<= 2;
  2056.         prodA |= prodB >>> 62;
  2057.         prodB <<= 2;

  2058.         /* Multiply by PI/4 */
  2059.         a = prodA >>> 32;
  2060.         b = prodA & 0xffffffffL;

  2061.         c = PI_O_4_BITS[0] >>> 32;
  2062.         d = PI_O_4_BITS[0] & 0xffffffffL;

  2063.         ac = a * c;
  2064.         bd = b * d;
  2065.         bc = b * c;
  2066.         ad = a * d;

  2067.         long prod2B = bd + (ad << 32);
  2068.         long prod2A = ac + (ad >>> 32);

  2069.         bita = (bd & 0x8000000000000000L) != 0;
  2070.         bitb = (ad & 0x80000000L ) != 0;
  2071.         bitsum = (prod2B & 0x8000000000000000L) != 0;

  2072.         /* Carry */
  2073.         if ( (bita && bitb) ||
  2074.                 ((bita || bitb) && !bitsum) ) {
  2075.             prod2A++;
  2076.         }

  2077.         bita = (prod2B & 0x8000000000000000L) != 0;
  2078.         bitb = (bc & 0x80000000L ) != 0;

  2079.         prod2B += bc << 32;
  2080.         prod2A += bc >>> 32;

  2081.         bitsum = (prod2B & 0x8000000000000000L) != 0;

  2082.         /* Carry */
  2083.         if ( (bita && bitb) ||
  2084.                 ((bita || bitb) && !bitsum) ) {
  2085.             prod2A++;
  2086.         }

  2087.         /* Multiply input by pio4bits[1] */
  2088.         c = PI_O_4_BITS[1] >>> 32;
  2089.         d = PI_O_4_BITS[1] & 0xffffffffL;
  2090.         ac = a * c;
  2091.         bc = b * c;
  2092.         ad = a * d;

  2093.         /* Collect terms */
  2094.         ac += (bc + ad) >>> 32;

  2095.         bita = (prod2B & 0x8000000000000000L) != 0;
  2096.         bitb = (ac & 0x8000000000000000L ) != 0;
  2097.         prod2B += ac;
  2098.         bitsum = (prod2B & 0x8000000000000000L) != 0;
  2099.         /* Carry */
  2100.         if ( (bita && bitb) ||
  2101.                 ((bita || bitb) && !bitsum) ) {
  2102.             prod2A++;
  2103.         }

  2104.         /* Multiply inputB by pio4bits[0] */
  2105.         a = prodB >>> 32;
  2106.         b = prodB & 0xffffffffL;
  2107.         c = PI_O_4_BITS[0] >>> 32;
  2108.         d = PI_O_4_BITS[0] & 0xffffffffL;
  2109.         ac = a * c;
  2110.         bc = b * c;
  2111.         ad = a * d;

  2112.         /* Collect terms */
  2113.         ac += (bc + ad) >>> 32;

  2114.         bita = (prod2B & 0x8000000000000000L) != 0;
  2115.         bitb = (ac & 0x8000000000000000L ) != 0;
  2116.         prod2B += ac;
  2117.         bitsum = (prod2B & 0x8000000000000000L) != 0;
  2118.         /* Carry */
  2119.         if ( (bita && bitb) ||
  2120.                 ((bita || bitb) && !bitsum) ) {
  2121.             prod2A++;
  2122.         }

  2123.         /* Convert to double */
  2124.         double tmpA = (prod2A >>> 12) / TWO_POWER_52;  // High order 52 bits
  2125.         double tmpB = (((prod2A & 0xfffL) << 40) + (prod2B >>> 24)) / TWO_POWER_52 / TWO_POWER_52; // Low bits

  2126.         double sumA = tmpA + tmpB;
  2127.         double sumB = -(sumA - tmpA - tmpB);

  2128.         /* Multiply by PI/2 and return */
  2129.         result[0] = intPart;
  2130.         result[1] = sumA * 2.0;
  2131.         result[2] = sumB * 2.0;
  2132.     }

  2133.     /**
  2134.      * Sine function.
  2135.      *
  2136.      * @param x Argument.
  2137.      * @return sin(x)
  2138.      */
  2139.     public static double sin(double x) {
  2140.         boolean negative = false;
  2141.         int quadrant = 0;
  2142.         double xa;
  2143.         double xb = 0.0;

  2144.         /* Take absolute value of the input */
  2145.         xa = x;
  2146.         if (x < 0) {
  2147.             negative = true;
  2148.             xa = -xa;
  2149.         }

  2150.         /* Check for zero and negative zero */
  2151.         if (xa == 0.0) {
  2152.             long bits = Double.doubleToRawLongBits(x);
  2153.             if (bits < 0) {
  2154.                 return -0.0;
  2155.             }
  2156.             return 0.0;
  2157.         }

  2158.         if (xa != xa || xa == Double.POSITIVE_INFINITY) {
  2159.             return Double.NaN;
  2160.         }

  2161.         /* Perform any argument reduction */
  2162.         if (xa > 3294198.0) {
  2163.             // PI * (2**20)
  2164.             // Argument too big for CodyWaite reduction.  Must use
  2165.             // PayneHanek.
  2166.             double[] reduceResults = new double[3];
  2167.             reducePayneHanek(xa, reduceResults);
  2168.             quadrant = ((int) reduceResults[0]) & 3;
  2169.             xa = reduceResults[1];
  2170.             xb = reduceResults[2];
  2171.         } else if (xa > 1.5707963267948966) {
  2172.             final CodyWaite cw = new CodyWaite(xa);
  2173.             quadrant = cw.getK() & 3;
  2174.             xa = cw.getRemA();
  2175.             xb = cw.getRemB();
  2176.         }

  2177.         if (negative) {
  2178.             quadrant ^= 2;  // Flip bit 1
  2179.         }

  2180.         switch (quadrant) {
  2181.             case 0:
  2182.                 return sinQ(xa, xb);
  2183.             case 1:
  2184.                 return cosQ(xa, xb);
  2185.             case 2:
  2186.                 return -sinQ(xa, xb);
  2187.             case 3:
  2188.                 return -cosQ(xa, xb);
  2189.             default:
  2190.                 return Double.NaN;
  2191.         }
  2192.     }

  2193.     /**
  2194.      * Cosine function.
  2195.      *
  2196.      * @param x Argument.
  2197.      * @return cos(x)
  2198.      */
  2199.     public static double cos(double x) {
  2200.         int quadrant = 0;

  2201.         /* Take absolute value of the input */
  2202.         double xa = x;
  2203.         if (x < 0) {
  2204.             xa = -xa;
  2205.         }

  2206.         if (xa != xa || xa == Double.POSITIVE_INFINITY) {
  2207.             return Double.NaN;
  2208.         }

  2209.         /* Perform any argument reduction */
  2210.         double xb = 0;
  2211.         if (xa > 3294198.0) {
  2212.             // PI * (2**20)
  2213.             // Argument too big for CodyWaite reduction.  Must use
  2214.             // PayneHanek.
  2215.             double[] reduceResults = new double[3];
  2216.             reducePayneHanek(xa, reduceResults);
  2217.             quadrant = ((int) reduceResults[0]) & 3;
  2218.             xa = reduceResults[1];
  2219.             xb = reduceResults[2];
  2220.         } else if (xa > 1.5707963267948966) {
  2221.             final CodyWaite cw = new CodyWaite(xa);
  2222.             quadrant = cw.getK() & 3;
  2223.             xa = cw.getRemA();
  2224.             xb = cw.getRemB();
  2225.         }

  2226.         //if (negative)
  2227.         //  quadrant = (quadrant + 2) % 4;

  2228.         switch (quadrant) {
  2229.             case 0:
  2230.                 return cosQ(xa, xb);
  2231.             case 1:
  2232.                 return -sinQ(xa, xb);
  2233.             case 2:
  2234.                 return -cosQ(xa, xb);
  2235.             case 3:
  2236.                 return sinQ(xa, xb);
  2237.             default:
  2238.                 return Double.NaN;
  2239.         }
  2240.     }

  2241.     /**
  2242.      * Combined Sine and Cosine function.
  2243.      *
  2244.      * @param x Argument.
  2245.      * @return [sin(x), cos(x)]
  2246.      */
  2247.     public static SinCos sinCos(double x) {
  2248.         boolean negative = false;
  2249.         int quadrant = 0;
  2250.         double xa;
  2251.         double xb = 0.0;

  2252.         /* Take absolute value of the input */
  2253.         xa = x;
  2254.         if (x < 0) {
  2255.             negative = true;
  2256.             xa = -xa;
  2257.         }

  2258.         /* Check for zero and negative zero */
  2259.         if (xa == 0.0) {
  2260.             long bits = Double.doubleToRawLongBits(x);
  2261.             if (bits < 0) {
  2262.                 return new SinCos(-0.0, 1.0);
  2263.             }
  2264.             return new SinCos(0.0, 1.0);
  2265.         }

  2266.         if (xa != xa || xa == Double.POSITIVE_INFINITY) {
  2267.             return new SinCos(Double.NaN, Double.NaN);
  2268.         }

  2269.         /* Perform any argument reduction */
  2270.         if (xa > 3294198.0) {
  2271.             // PI * (2**20)
  2272.             // Argument too big for CodyWaite reduction.  Must use
  2273.             // PayneHanek.
  2274.             double[] reduceResults = new double[3];
  2275.             reducePayneHanek(xa, reduceResults);
  2276.             quadrant = ((int) reduceResults[0]) & 3;
  2277.             xa = reduceResults[1];
  2278.             xb = reduceResults[2];
  2279.         } else if (xa > 1.5707963267948966) {
  2280.             final CodyWaite cw = new CodyWaite(xa);
  2281.             quadrant = cw.getK() & 3;
  2282.             xa = cw.getRemA();
  2283.             xb = cw.getRemB();
  2284.         }

  2285.         switch (quadrant) {
  2286.             case 0:
  2287.                 return new SinCos(negative ? -sinQ(xa, xb) :  sinQ(xa, xb),  cosQ(xa, xb));
  2288.             case 1:
  2289.                 return new SinCos(negative ? -cosQ(xa, xb) :  cosQ(xa, xb), -sinQ(xa, xb));
  2290.             case 2:
  2291.                 return new SinCos(negative ?  sinQ(xa, xb) : -sinQ(xa, xb), -cosQ(xa, xb));
  2292.             case 3:
  2293.                 return new SinCos(negative ?  cosQ(xa, xb) : -cosQ(xa, xb),  sinQ(xa, xb));
  2294.             default:
  2295.                 return new SinCos(Double.NaN, Double.NaN);
  2296.         }
  2297.     }

  2298.     /**
  2299.      * Combined Sine and Cosine function.
  2300.      *
  2301.      * @param x Argument.
  2302.      * @param <T> the type of the field element
  2303.      * @return [sin(x), cos(x)]
  2304.      * @since 1.4
  2305.      */
  2306.     public static <T extends CalculusFieldElement<T>> FieldSinCos<T> sinCos(T x) {
  2307.         return x.sinCos();
  2308.     }

  2309.     /**
  2310.      * Tangent function.
  2311.      *
  2312.      * @param x Argument.
  2313.      * @return tan(x)
  2314.      */
  2315.     public static double tan(double x) {
  2316.         boolean negative = false;
  2317.         int quadrant = 0;

  2318.         /* Take absolute value of the input */
  2319.         double xa = x;
  2320.         if (x < 0) {
  2321.             negative = true;
  2322.             xa = -xa;
  2323.         }

  2324.         /* Check for zero and negative zero */
  2325.         if (xa == 0.0) {
  2326.             long bits = Double.doubleToRawLongBits(x);
  2327.             if (bits < 0) {
  2328.                 return -0.0;
  2329.             }
  2330.             return 0.0;
  2331.         }

  2332.         if (xa != xa || xa == Double.POSITIVE_INFINITY) {
  2333.             return Double.NaN;
  2334.         }

  2335.         /* Perform any argument reduction */
  2336.         double xb = 0;
  2337.         if (xa > 3294198.0) {
  2338.             // PI * (2**20)
  2339.             // Argument too big for CodyWaite reduction.  Must use
  2340.             // PayneHanek.
  2341.             double[] reduceResults = new double[3];
  2342.             reducePayneHanek(xa, reduceResults);
  2343.             quadrant = ((int) reduceResults[0]) & 3;
  2344.             xa = reduceResults[1];
  2345.             xb = reduceResults[2];
  2346.         } else if (xa > 1.5707963267948966) {
  2347.             final CodyWaite cw = new CodyWaite(xa);
  2348.             quadrant = cw.getK() & 3;
  2349.             xa = cw.getRemA();
  2350.             xb = cw.getRemB();
  2351.         }

  2352.         if (xa > 1.5) {
  2353.             // Accuracy suffers between 1.5 and PI/2
  2354.             final double pi2a = 1.5707963267948966;
  2355.             final double pi2b = 6.123233995736766E-17;

  2356.             final double a = pi2a - xa;
  2357.             double b = -(a - pi2a + xa);
  2358.             b += pi2b - xb;

  2359.             xa = a + b;
  2360.             xb = -(xa - a - b);
  2361.             quadrant ^= 1;
  2362.             negative ^= true;
  2363.         }

  2364.         double result;
  2365.         if ((quadrant & 1) == 0) {
  2366.             result = tanQ(xa, xb, false);
  2367.         } else {
  2368.             result = -tanQ(xa, xb, true);
  2369.         }

  2370.         if (negative) {
  2371.             result = -result;
  2372.         }

  2373.         return result;
  2374.     }

  2375.     /**
  2376.      * Arctangent function
  2377.      *  @param x a number
  2378.      *  @return atan(x)
  2379.      */
  2380.     public static double atan(double x) {
  2381.         return atan(x, 0.0, false);
  2382.     }

  2383.     /** Internal helper function to compute arctangent.
  2384.      * @param xa number from which arctangent is requested
  2385.      * @param xb extra bits for x (may be 0.0)
  2386.      * @param leftPlane if true, result angle must be put in the left half plane
  2387.      * @return atan(xa + xb) (or angle shifted by {@code PI} if leftPlane is true)
  2388.      */
  2389.     private static double atan(double xa, double xb, boolean leftPlane) {
  2390.         if (xa == 0.0) { // Matches +/- 0.0; return correct sign
  2391.             return leftPlane ? copySign(Math.PI, xa) : xa;
  2392.         }

  2393.         final boolean negate;
  2394.         if (xa < 0) {
  2395.             // negative
  2396.             xa = -xa;
  2397.             xb = -xb;
  2398.             negate = true;
  2399.         } else {
  2400.             negate = false;
  2401.         }

  2402.         if (xa > 1.633123935319537E16) { // Very large input
  2403.             return (negate ^ leftPlane) ? (-Math.PI * F_1_2) : (Math.PI * F_1_2);
  2404.         }

  2405.         /* Estimate the closest tabulated arctan value, compute eps = xa-tangentTable */
  2406.         final int idx;
  2407.         if (xa < 1) {
  2408.             idx = (int) (((-1.7168146928204136 * xa * xa + 8.0) * xa) + 0.5);
  2409.         } else {
  2410.             final double oneOverXa = 1 / xa;
  2411.             idx = (int) (-((-1.7168146928204136 * oneOverXa * oneOverXa + 8.0) * oneOverXa) + 13.07);
  2412.         }

  2413.         final double ttA = TANGENT_TABLE_A[idx];
  2414.         final double ttB = TANGENT_TABLE_B[idx];

  2415.         double epsA = xa - ttA;
  2416.         double epsB = -(epsA - xa + ttA);
  2417.         epsB += xb - ttB;

  2418.         double temp = epsA + epsB;
  2419.         epsB = -(temp - epsA - epsB);
  2420.         epsA = temp;

  2421.         /* Compute eps = eps / (1.0 + xa*tangent) */
  2422.         temp = xa * HEX_40000000;
  2423.         double ya = xa + temp - temp;
  2424.         double yb = xb + xa - ya;
  2425.         xa = ya;
  2426.         xb += yb;

  2427.         //if (idx > 8 || idx == 0)
  2428.         if (idx == 0) {
  2429.             /* If the slope of the arctan is gentle enough (< 0.45), this approximation will suffice */
  2430.             //double denom = 1.0 / (1.0 + xa*tangentTableA[idx] + xb*tangentTableA[idx] + xa*tangentTableB[idx] + xb*tangentTableB[idx]);
  2431.             final double denom = 1d / (1d + (xa + xb) * (ttA + ttB));
  2432.             //double denom = 1.0 / (1.0 + xa*tangentTableA[idx]);
  2433.             ya = epsA * denom;
  2434.             yb = epsB * denom;
  2435.         } else {
  2436.             double temp2 = xa * ttA;
  2437.             double za = 1d + temp2;
  2438.             double zb = -(za - 1d - temp2);
  2439.             temp2 = xb * ttA + xa * ttB;
  2440.             temp = za + temp2;
  2441.             zb += -(temp - za - temp2);
  2442.             za = temp;

  2443.             zb += xb * ttB;
  2444.             ya = epsA / za;

  2445.             temp = ya * HEX_40000000;
  2446.             final double yaa = (ya + temp) - temp;
  2447.             final double yab = ya - yaa;

  2448.             temp = za * HEX_40000000;
  2449.             final double zaa = (za + temp) - temp;
  2450.             final double zab = za - zaa;

  2451.             /* Correct for rounding in division */
  2452.             yb = (epsA - yaa * zaa - yaa * zab - yab * zaa - yab * zab) / za;

  2453.             yb += -epsA * zb / za / za;
  2454.             yb += epsB / za;
  2455.         }


  2456.         epsA = ya;
  2457.         epsB = yb;

  2458.         /* Evaluate polynomial */
  2459.         final double epsA2 = epsA * epsA;

  2460.         /*
  2461.     yb = -0.09001346640161823;
  2462.     yb = yb * epsA2 + 0.11110718400605211;
  2463.     yb = yb * epsA2 + -0.1428571349122913;
  2464.     yb = yb * epsA2 + 0.19999999999273194;
  2465.     yb = yb * epsA2 + -0.33333333333333093;
  2466.     yb = yb * epsA2 * epsA;
  2467.          */

  2468.         yb = 0.07490822288864472;
  2469.         yb = yb * epsA2 - 0.09088450866185192;
  2470.         yb = yb * epsA2 + 0.11111095942313305;
  2471.         yb = yb * epsA2 - 0.1428571423679182;
  2472.         yb = yb * epsA2 + 0.19999999999923582;
  2473.         yb = yb * epsA2 - 0.33333333333333287;
  2474.         yb = yb * epsA2 * epsA;


  2475.         ya = epsA;

  2476.         temp = ya + yb;
  2477.         yb = -(temp - ya - yb);
  2478.         ya = temp;

  2479.         /* Add in effect of epsB.   atan'(x) = 1/(1+x^2) */
  2480.         yb += epsB / (1d + epsA * epsA);

  2481.         final double eighths = EIGHTHS[idx];

  2482.         //result = yb + eighths[idx] + ya;
  2483.         double za = eighths + ya;
  2484.         double zb = -(za - eighths - ya);
  2485.         temp = za + yb;
  2486.         zb += -(temp - za - yb);
  2487.         za = temp;

  2488.         double result = za + zb;

  2489.         if (leftPlane) {
  2490.             // Result is in the left plane
  2491.             final double resultb = -(result - za - zb);
  2492.             final double pia = 1.5707963267948966 * 2;
  2493.             final double pib = 6.123233995736766E-17 * 2;

  2494.             za = pia - result;
  2495.             zb = -(za - pia + result);
  2496.             zb += pib - resultb;

  2497.             result = za + zb;
  2498.         }


  2499.         if (negate ^ leftPlane) {
  2500.             result = -result;
  2501.         }

  2502.         return result;
  2503.     }

  2504.     /**
  2505.      * Two arguments arctangent function
  2506.      * @param y ordinate
  2507.      * @param x abscissa
  2508.      * @return phase angle of point (x,y) between {@code -PI} and {@code PI}
  2509.      */
  2510.     public static double atan2(double y, double x) {
  2511.         if (Double.isNaN(x) || Double.isNaN(y)) {
  2512.             return Double.NaN;
  2513.         }

  2514.         if (y == 0) {
  2515.             final double result = x * y;
  2516.             final double invx = 1d / x;

  2517.             if (invx == 0) { // X is infinite
  2518.                 if (x > 0) {
  2519.                     return y; // return +/- 0.0
  2520.                 } else {
  2521.                     return copySign(Math.PI, y);
  2522.                 }
  2523.             }

  2524.             if (x < 0 || invx < 0) {
  2525.                 return copySign(Math.PI, y);
  2526.             } else {
  2527.                 return result;
  2528.             }
  2529.         }

  2530.         // y cannot now be zero

  2531.         if (y == Double.POSITIVE_INFINITY) {
  2532.             if (x == Double.POSITIVE_INFINITY) {
  2533.                 return Math.PI * F_1_4;
  2534.             }

  2535.             if (x == Double.NEGATIVE_INFINITY) {
  2536.                 return Math.PI * F_3_4;
  2537.             }

  2538.             return Math.PI * F_1_2;
  2539.         }

  2540.         if (y == Double.NEGATIVE_INFINITY) {
  2541.             if (x == Double.POSITIVE_INFINITY) {
  2542.                 return -Math.PI * F_1_4;
  2543.             }

  2544.             if (x == Double.NEGATIVE_INFINITY) {
  2545.                 return -Math.PI * F_3_4;
  2546.             }

  2547.             return -Math.PI * F_1_2;
  2548.         }

  2549.         if (x == Double.POSITIVE_INFINITY) {
  2550.             return copySign(0d, y);
  2551.         }

  2552.         if (x == Double.NEGATIVE_INFINITY)
  2553.         {
  2554.             return copySign(Math.PI, y);
  2555.         }

  2556.         // Neither y nor x can be infinite or NAN here

  2557.         if (x == 0) {
  2558.             return copySign(Math.PI * F_1_2, y);
  2559.         }

  2560.         // Compute ratio r = y/x
  2561.         final double r = y / x;
  2562.         if (Double.isInfinite(r)) { // bypass calculations that can create NaN
  2563.             return atan(r, 0, x < 0);
  2564.         }

  2565.         double ra = doubleHighPart(r);
  2566.         double rb = r - ra;

  2567.         // Split x
  2568.         final double xa = doubleHighPart(x);
  2569.         final double xb = x - xa;

  2570.         rb += (y - ra * xa - ra * xb - rb * xa - rb * xb) / x;

  2571.         final double temp = ra + rb;
  2572.         rb = -(temp - ra - rb);
  2573.         ra = temp;

  2574.         if (ra == 0) { // Fix up the sign so atan works correctly
  2575.             ra = copySign(0d, y);
  2576.         }

  2577.         // Call atan
  2578.         return atan(ra, rb, x < 0);

  2579.     }

  2580.     /** Compute the arc sine of a number.
  2581.      * @param x number on which evaluation is done
  2582.      * @return arc sine of x
  2583.      */
  2584.     public static double asin(double x) {
  2585.       if (Double.isNaN(x)) {
  2586.           return Double.NaN;
  2587.       }

  2588.       if (x > 1.0 || x < -1.0) {
  2589.           return Double.NaN;
  2590.       }

  2591.       if (x == 1.0) {
  2592.           return Math.PI/2.0;
  2593.       }

  2594.       if (x == -1.0) {
  2595.           return -Math.PI/2.0;
  2596.       }

  2597.       if (x == 0.0) { // Matches +/- 0.0; return correct sign
  2598.           return x;
  2599.       }

  2600.       /* Compute asin(x) = atan(x/sqrt(1-x*x)) */

  2601.       /* Split x */
  2602.       double temp = x * HEX_40000000;
  2603.       final double xa = x + temp - temp;
  2604.       final double xb = x - xa;

  2605.       /* Square it */
  2606.       double ya = xa*xa;
  2607.       double yb = xa*xb*2.0 + xb*xb;

  2608.       /* Subtract from 1 */
  2609.       ya = -ya;
  2610.       yb = -yb;

  2611.       double za = 1.0 + ya;
  2612.       double zb = -(za - 1.0 - ya);

  2613.       temp = za + yb;
  2614.       zb += -(temp - za - yb);
  2615.       za = temp;

  2616.       /* Square root */
  2617.       double y;
  2618.       y = sqrt(za);
  2619.       temp = y * HEX_40000000;
  2620.       ya = y + temp - temp;
  2621.       yb = y - ya;

  2622.       /* Extend precision of sqrt */
  2623.       yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y);

  2624.       /* Contribution of zb to sqrt */
  2625.       double dx = zb / (2.0*y);

  2626.       // Compute ratio r = x/y
  2627.       double r = x/y;
  2628.       temp = r * HEX_40000000;
  2629.       double ra = r + temp - temp;
  2630.       double rb = r - ra;

  2631.       rb += (x - ra*ya - ra*yb - rb*ya - rb*yb) / y;  // Correct for rounding in division
  2632.       rb += -x * dx / y / y;  // Add in effect additional bits of sqrt.

  2633.       temp = ra + rb;
  2634.       rb = -(temp - ra - rb);
  2635.       ra = temp;

  2636.       return atan(ra, rb, false);
  2637.     }

  2638.     /** Compute the arc cosine of a number.
  2639.      * @param x number on which evaluation is done
  2640.      * @return arc cosine of x
  2641.      */
  2642.     public static double acos(double x) {
  2643.       if (Double.isNaN(x)) {
  2644.           return Double.NaN;
  2645.       }

  2646.       if (x > 1.0 || x < -1.0) {
  2647.           return Double.NaN;
  2648.       }

  2649.       if (x == -1.0) {
  2650.           return Math.PI;
  2651.       }

  2652.       if (x == 1.0) {
  2653.           return 0.0;
  2654.       }

  2655.       if (x == 0) {
  2656.           return Math.PI/2.0;
  2657.       }

  2658.       /* Compute acos(x) = atan(sqrt(1-x*x)/x) */

  2659.       /* Split x */
  2660.       double temp = x * HEX_40000000;
  2661.       final double xa = x + temp - temp;
  2662.       final double xb = x - xa;

  2663.       /* Square it */
  2664.       double ya = xa*xa;
  2665.       double yb = xa*xb*2.0 + xb*xb;

  2666.       /* Subtract from 1 */
  2667.       ya = -ya;
  2668.       yb = -yb;

  2669.       double za = 1.0 + ya;
  2670.       double zb = -(za - 1.0 - ya);

  2671.       temp = za + yb;
  2672.       zb += -(temp - za - yb);
  2673.       za = temp;

  2674.       /* Square root */
  2675.       double y = sqrt(za);
  2676.       temp = y * HEX_40000000;
  2677.       ya = y + temp - temp;
  2678.       yb = y - ya;

  2679.       /* Extend precision of sqrt */
  2680.       yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y);

  2681.       /* Contribution of zb to sqrt */
  2682.       yb += zb / (2.0*y);
  2683.       y = ya+yb;
  2684.       yb = -(y - ya - yb);

  2685.       // Compute ratio r = y/x
  2686.       double r = y/x;

  2687.       // Did r overflow?
  2688.       if (Double.isInfinite(r)) { // x is effectively zero
  2689.           return Math.PI/2; // so return the appropriate value
  2690.       }

  2691.       double ra = doubleHighPart(r);
  2692.       double rb = r - ra;

  2693.       rb += (y - ra*xa - ra*xb - rb*xa - rb*xb) / x;  // Correct for rounding in division
  2694.       rb += yb / x;  // Add in effect additional bits of sqrt.

  2695.       temp = ra + rb;
  2696.       rb = -(temp - ra - rb);
  2697.       ra = temp;

  2698.       return atan(ra, rb, x<0);
  2699.     }

  2700.     /** Compute the cubic root of a number.
  2701.      * @param x number on which evaluation is done
  2702.      * @return cubic root of x
  2703.      */
  2704.     public static double cbrt(double x) {
  2705.       /* Convert input double to bits */
  2706.       long inbits = Double.doubleToRawLongBits(x);
  2707.       int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
  2708.       boolean subnormal = false;

  2709.       if (exponent == -1023) {
  2710.           if (x == 0) {
  2711.               return x;
  2712.           }

  2713.           /* Subnormal, so normalize */
  2714.           subnormal = true;
  2715.           x *= 1.8014398509481984E16;  // 2^54
  2716.           inbits = Double.doubleToRawLongBits(x);
  2717.           exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
  2718.       }

  2719.       if (exponent == 1024) {
  2720.           // Nan or infinity.  Don't care which.
  2721.           return x;
  2722.       }

  2723.       /* Divide the exponent by 3 */
  2724.       int exp3 = exponent / 3;

  2725.       /* p2 will be the nearest power of 2 to x with its exponent divided by 3 */
  2726.       double p2 = Double.longBitsToDouble((inbits & 0x8000000000000000L) |
  2727.                                           (long)(((exp3 + 1023) & 0x7ff)) << 52);

  2728.       /* This will be a number between 1 and 2 */
  2729.       final double mant = Double.longBitsToDouble((inbits & 0x000fffffffffffffL) | 0x3ff0000000000000L);

  2730.       /* Estimate the cube root of mant by polynomial */
  2731.       double est = -0.010714690733195933;
  2732.       est = est * mant + 0.0875862700108075;
  2733.       est = est * mant + -0.3058015757857271;
  2734.       est = est * mant + 0.7249995199969751;
  2735.       est = est * mant + 0.5039018405998233;

  2736.       est *= CBRTTWO[exponent % 3 + 2];

  2737.       // est should now be good to about 15 bits of precision.   Do 2 rounds of
  2738.       // Newton's method to get closer,  this should get us full double precision
  2739.       // Scale down x for the purpose of doing newtons method.  This avoids over/under flows.
  2740.       final double xs = x / (p2*p2*p2);
  2741.       est += (xs - est*est*est) / (3*est*est);
  2742.       est += (xs - est*est*est) / (3*est*est);

  2743.       // Do one round of Newton's method in extended precision to get the last bit right.
  2744.       double temp = est * HEX_40000000;
  2745.       double ya = est + temp - temp;
  2746.       double yb = est - ya;

  2747.       double za = ya * ya;
  2748.       double zb = ya * yb * 2.0 + yb * yb;
  2749.       temp = za * HEX_40000000;
  2750.       double temp2 = za + temp - temp;
  2751.       zb += za - temp2;
  2752.       za = temp2;

  2753.       zb = za * yb + ya * zb + zb * yb;
  2754.       za *= ya;

  2755.       double na = xs - za;
  2756.       double nb = -(na - xs + za);
  2757.       nb -= zb;

  2758.       est += (na+nb)/(3*est*est);

  2759.       /* Scale by a power of two, so this is exact. */
  2760.       est *= p2;

  2761.       if (subnormal) {
  2762.           est *= 3.814697265625E-6;  // 2^-18
  2763.       }

  2764.       return est;
  2765.     }

  2766.     /**
  2767.      *  Convert degrees to radians, with error of less than 0.5 ULP
  2768.      *  @param x angle in degrees
  2769.      *  @return x converted into radians
  2770.      */
  2771.     public static double toRadians(double x)
  2772.     {
  2773.         if (Double.isInfinite(x) || x == 0.0) { // Matches +/- 0.0; return correct sign
  2774.             return x;
  2775.         }

  2776.         // These are PI/180 split into high and low order bits
  2777.         final double facta = 0.01745329052209854;
  2778.         final double factb = 1.997844754509471E-9;

  2779.         double xa = doubleHighPart(x);
  2780.         double xb = x - xa;

  2781.         double result = xb * factb + xb * facta + xa * factb + xa * facta;
  2782.         if (result == 0) {
  2783.             result *= x; // ensure correct sign if calculation underflows
  2784.         }
  2785.         return result;
  2786.     }

  2787.     /**
  2788.      *  Convert radians to degrees, with error of less than 0.5 ULP
  2789.      *  @param x angle in radians
  2790.      *  @return x converted into degrees
  2791.      */
  2792.     public static double toDegrees(double x)
  2793.     {
  2794.         if (Double.isInfinite(x) || x == 0.0) { // Matches +/- 0.0; return correct sign
  2795.             return x;
  2796.         }

  2797.         // These are 180/PI split into high and low order bits
  2798.         final double facta = 57.2957763671875;
  2799.         final double factb = 3.145894820876798E-6;

  2800.         double xa = doubleHighPart(x);
  2801.         double xb = x - xa;

  2802.         return xb * factb + xb * facta + xa * factb + xa * facta;
  2803.     }

  2804.     /**
  2805.      * Absolute value.
  2806.      * @param x number from which absolute value is requested
  2807.      * @return abs(x)
  2808.      */
  2809.     public static int abs(final int x) {
  2810.         final int i = x >>> 31;
  2811.         return (x ^ (~i + 1)) + i;
  2812.     }

  2813.     /**
  2814.      * Absolute value.
  2815.      * @param x number from which absolute value is requested
  2816.      * @return abs(x)
  2817.      */
  2818.     public static long abs(final long x) {
  2819.         final long l = x >>> 63;
  2820.         // l is one if x negative zero else
  2821.         // ~l+1 is zero if x is positive, -1 if x is negative
  2822.         // x^(~l+1) is x is x is positive, ~x if x is negative
  2823.         // add around
  2824.         return (x ^ (~l + 1)) + l;
  2825.     }

  2826.     /**
  2827.      * Absolute value.
  2828.      * @param x number from which absolute value is requested
  2829.      * @return abs(x), or throws an exception for {@code Integer.MIN_VALUE}
  2830.      * @since 2.0
  2831.      */
  2832.     public static int absExact(final int x) {
  2833.         if (x == Integer.MIN_VALUE) {
  2834.             throw new ArithmeticException();
  2835.         }
  2836.         return abs(x);
  2837.     }

  2838.     /**
  2839.      * Absolute value.
  2840.      * @param x number from which absolute value is requested
  2841.      * @return abs(x), or throws an exception for {@code Long.MIN_VALUE}
  2842.      * @since 2.0
  2843.      */
  2844.     public static long absExact(final long x) {
  2845.         if (x == Long.MIN_VALUE) {
  2846.             throw new ArithmeticException();
  2847.         }
  2848.         return abs(x);
  2849.     }

  2850.     /**
  2851.      * Absolute value.
  2852.      * @param x number from which absolute value is requested
  2853.      * @return abs(x)
  2854.      * @since 2.0
  2855.      */
  2856.     public static float abs(final float x) {
  2857.         return Float.intBitsToFloat(MASK_NON_SIGN_INT & Float.floatToRawIntBits(x));
  2858.     }

  2859.     /**
  2860.      * Absolute value.
  2861.      * @param x number from which absolute value is requested
  2862.      * @return abs(x)
  2863.      */
  2864.     public static double abs(double x) {
  2865.         return Double.longBitsToDouble(MASK_NON_SIGN_LONG & Double.doubleToRawLongBits(x));
  2866.     }

  2867.     /**
  2868.      * Negates the argument.
  2869.      * @param x number from which opposite value is requested
  2870.      * @return -x, or throws an exception for {@code Integer.MIN_VALUE}
  2871.      * @since 2.0
  2872.      */
  2873.     public static int negateExact(final int x) {
  2874.         if (x == Integer.MIN_VALUE) {
  2875.             throw new ArithmeticException();
  2876.         }
  2877.         return -x;
  2878.     }

  2879.     /**
  2880.      * Negates the argument.
  2881.      * @param x number from which opposite value is requested
  2882.      * @return -x, or throws an exception for {@code Long.MIN_VALUE}
  2883.      * @since 2.0
  2884.      */
  2885.     public static long negateExact(final long x) {
  2886.         if (x == Long.MIN_VALUE) {
  2887.             throw new ArithmeticException();
  2888.         }
  2889.         return -x;
  2890.     }

  2891.     /**
  2892.      * Compute least significant bit (Unit in Last Position) for a number.
  2893.      * @param x number from which ulp is requested
  2894.      * @return ulp(x)
  2895.      */
  2896.     public static double ulp(double x) {
  2897.         if (Double.isInfinite(x)) {
  2898.             return Double.POSITIVE_INFINITY;
  2899.         }
  2900.         return abs(x - Double.longBitsToDouble(Double.doubleToRawLongBits(x) ^ 1));
  2901.     }

  2902.     /**
  2903.      * Compute least significant bit (Unit in Last Position) for a number.
  2904.      * @param x number from which ulp is requested
  2905.      * @return ulp(x)
  2906.      */
  2907.     public static float ulp(float x) {
  2908.         if (Float.isInfinite(x)) {
  2909.             return Float.POSITIVE_INFINITY;
  2910.         }
  2911.         return abs(x - Float.intBitsToFloat(Float.floatToRawIntBits(x) ^ 1));
  2912.     }

  2913.     /**
  2914.      * Multiply a double number by a power of 2.
  2915.      * @param d number to multiply
  2916.      * @param n power of 2
  2917.      * @return d &times; 2<sup>n</sup>
  2918.      */
  2919.     public static double scalb(final double d, final int n) {

  2920.         // first simple and fast handling when 2^n can be represented using normal numbers
  2921.         if ((n > -1023) && (n < 1024)) {
  2922.             return d * Double.longBitsToDouble(((long) (n + 1023)) << 52);
  2923.         }

  2924.         // handle special cases
  2925.         if (Double.isNaN(d) || Double.isInfinite(d) || (d == 0)) {
  2926.             return d;
  2927.         }
  2928.         if (n < -2098) {
  2929.             return (d > 0) ? 0.0 : -0.0;
  2930.         }
  2931.         if (n > 2097) {
  2932.             return (d > 0) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
  2933.         }

  2934.         // decompose d
  2935.         final long bits = Double.doubleToRawLongBits(d);
  2936.         final long sign = bits & 0x8000000000000000L;
  2937.         int  exponent   = ((int) (bits >>> 52)) & 0x7ff;
  2938.         long mantissa   = bits & 0x000fffffffffffffL;

  2939.         // compute scaled exponent
  2940.         int scaledExponent = exponent + n;

  2941.         if (n < 0) {
  2942.             // we are really in the case n <= -1023
  2943.             if (scaledExponent > 0) {
  2944.                 // both the input and the result are normal numbers, we only adjust the exponent
  2945.                 return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
  2946.             } else if (scaledExponent > -53) {
  2947.                 // the input is a normal number and the result is a subnormal number

  2948.                 // recover the hidden mantissa bit
  2949.                 mantissa |= 1L << 52;

  2950.                 // scales down complete mantissa, hence losing least significant bits
  2951.                 final long mostSignificantLostBit = mantissa & (1L << (-scaledExponent));
  2952.                 mantissa >>>= 1 - scaledExponent;
  2953.                 if (mostSignificantLostBit != 0) {
  2954.                     // we need to add 1 bit to round up the result
  2955.                     mantissa++;
  2956.                 }
  2957.                 return Double.longBitsToDouble(sign | mantissa);

  2958.             } else {
  2959.                 // no need to compute the mantissa, the number scales down to 0
  2960.                 return (sign == 0L) ? 0.0 : -0.0;
  2961.             }
  2962.         } else {
  2963.             // we are really in the case n >= 1024
  2964.             if (exponent == 0) {

  2965.                 // the input number is subnormal, normalize it
  2966.                 while ((mantissa >>> 52) != 1) {
  2967.                     mantissa <<= 1;
  2968.                     --scaledExponent;
  2969.                 }
  2970.                 ++scaledExponent;
  2971.                 mantissa &= 0x000fffffffffffffL;

  2972.                 if (scaledExponent < 2047) {
  2973.                     return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
  2974.                 } else {
  2975.                     return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
  2976.                 }

  2977.             } else if (scaledExponent < 2047) {
  2978.                 return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
  2979.             } else {
  2980.                 return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
  2981.             }
  2982.         }

  2983.     }

  2984.     /**
  2985.      * Multiply a float number by a power of 2.
  2986.      * @param f number to multiply
  2987.      * @param n power of 2
  2988.      * @return f &times; 2<sup>n</sup>
  2989.      */
  2990.     public static float scalb(final float f, final int n) {

  2991.         // first simple and fast handling when 2^n can be represented using normal numbers
  2992.         if ((n > -127) && (n < 128)) {
  2993.             return f * Float.intBitsToFloat((n + 127) << 23);
  2994.         }

  2995.         // handle special cases
  2996.         if (Float.isNaN(f) || Float.isInfinite(f) || (f == 0f)) {
  2997.             return f;
  2998.         }
  2999.         if (n < -277) {
  3000.             return (f > 0) ? 0.0f : -0.0f;
  3001.         }
  3002.         if (n > 276) {
  3003.             return (f > 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
  3004.         }

  3005.         // decompose f
  3006.         final int bits = Float.floatToIntBits(f);
  3007.         final int sign = bits & 0x80000000;
  3008.         int  exponent  = (bits >>> 23) & 0xff;
  3009.         int mantissa   = bits & 0x007fffff;

  3010.         // compute scaled exponent
  3011.         int scaledExponent = exponent + n;

  3012.         if (n < 0) {
  3013.             // we are really in the case n <= -127
  3014.             if (scaledExponent > 0) {
  3015.                 // both the input and the result are normal numbers, we only adjust the exponent
  3016.                 return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
  3017.             } else if (scaledExponent > -24) {
  3018.                 // the input is a normal number and the result is a subnormal number

  3019.                 // recover the hidden mantissa bit
  3020.                 mantissa |= 1 << 23;

  3021.                 // scales down complete mantissa, hence losing least significant bits
  3022.                 final int mostSignificantLostBit = mantissa & (1 << (-scaledExponent));
  3023.                 mantissa >>>= 1 - scaledExponent;
  3024.                 if (mostSignificantLostBit != 0) {
  3025.                     // we need to add 1 bit to round up the result
  3026.                     mantissa++;
  3027.                 }
  3028.                 return Float.intBitsToFloat(sign | mantissa);

  3029.             } else {
  3030.                 // no need to compute the mantissa, the number scales down to 0
  3031.                 return (sign == 0) ? 0.0f : -0.0f;
  3032.             }
  3033.         } else {
  3034.             // we are really in the case n >= 128
  3035.             if (exponent == 0) {

  3036.                 // the input number is subnormal, normalize it
  3037.                 while ((mantissa >>> 23) != 1) {
  3038.                     mantissa <<= 1;
  3039.                     --scaledExponent;
  3040.                 }
  3041.                 ++scaledExponent;
  3042.                 mantissa &= 0x007fffff;

  3043.                 if (scaledExponent < 255) {
  3044.                     return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
  3045.                 } else {
  3046.                     return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
  3047.                 }

  3048.             } else if (scaledExponent < 255) {
  3049.                 return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
  3050.             } else {
  3051.                 return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
  3052.             }
  3053.         }

  3054.     }

  3055.     /**
  3056.      * Get the next machine representable number after a number, moving
  3057.      * in the direction of another number.
  3058.      * <p>
  3059.      * The ordering is as follows (increasing):
  3060.      * </p>
  3061.      * <ul>
  3062.      * <li>-INFINITY</li>
  3063.      * <li>-MAX_VALUE</li>
  3064.      * <li>-MIN_VALUE</li>
  3065.      * <li>-0.0</li>
  3066.      * <li>+0.0</li>
  3067.      * <li>+MIN_VALUE</li>
  3068.      * <li>+MAX_VALUE</li>
  3069.      * <li>+INFINITY</li>
  3070.      * </ul>
  3071.      * <p>
  3072.      * If arguments compare equal, then the second argument is returned.
  3073.      * </p>
  3074.      * <p>
  3075.      * If {@code direction} is greater than {@code d},
  3076.      * the smallest machine representable number strictly greater than
  3077.      * {@code d} is returned; if less, then the largest representable number
  3078.      * strictly less than {@code d} is returned.
  3079.      * </p>
  3080.      * <p>
  3081.      * If {@code d} is infinite and direction does not
  3082.      * bring it back to finite numbers, it is returned unchanged.
  3083.      * </p>
  3084.      *
  3085.      * @param d base number
  3086.      * @param direction (the only important thing is whether
  3087.      * {@code direction} is greater or smaller than {@code d})
  3088.      * @return the next machine representable number in the specified direction
  3089.      */
  3090.     public static double nextAfter(double d, double direction) {

  3091.         // handling of some important special cases
  3092.         if (Double.isNaN(d) || Double.isNaN(direction)) {
  3093.             return Double.NaN;
  3094.         } else if (d == direction) {
  3095.             return direction;
  3096.         } else if (Double.isInfinite(d)) {
  3097.             return (d < 0) ? -Double.MAX_VALUE : Double.MAX_VALUE;
  3098.         } else if (d == 0) {
  3099.             return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE;
  3100.         }
  3101.         // special cases MAX_VALUE to infinity and  MIN_VALUE to 0
  3102.         // are handled just as normal numbers
  3103.         // can use raw bits since already dealt with infinity and NaN
  3104.         final long bits = Double.doubleToRawLongBits(d);
  3105.         final long sign = bits & 0x8000000000000000L;
  3106.         if ((direction < d) ^ (sign == 0L)) {
  3107.             return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) + 1));
  3108.         } else {
  3109.             return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) - 1));
  3110.         }

  3111.     }

  3112.     /**
  3113.      * Get the next machine representable number after a number, moving
  3114.      * in the direction of another number.
  3115.      * <p>* The ordering is as follows (increasing):</p>
  3116.      * <ul>
  3117.      * <li>-INFINITY</li>
  3118.      * <li>-MAX_VALUE</li>
  3119.      * <li>-MIN_VALUE</li>
  3120.      * <li>-0.0</li>
  3121.      * <li>+0.0</li>
  3122.      * <li>+MIN_VALUE</li>
  3123.      * <li>+MAX_VALUE</li>
  3124.      * <li>+INFINITY</li>
  3125.      * </ul>
  3126.      * <p>
  3127.      * If arguments compare equal, then the second argument is returned.
  3128.      * </p>
  3129.      * <p>
  3130.      * If {@code direction} is greater than {@code f},
  3131.      * the smallest machine representable number strictly greater than
  3132.      * {@code f} is returned; if less, then the largest representable number
  3133.      * strictly less than {@code f} is returned.
  3134.      * </p>
  3135.      * <p>
  3136.      * If {@code f} is infinite and direction does not
  3137.      * bring it back to finite numbers, it is returned unchanged.
  3138.      * </p>
  3139.      *
  3140.      * @param f base number
  3141.      * @param direction (the only important thing is whether
  3142.      * {@code direction} is greater or smaller than {@code f})
  3143.      * @return the next machine representable number in the specified direction
  3144.      */
  3145.     public static float nextAfter(final float f, final double direction) {

  3146.         // handling of some important special cases
  3147.         if (Double.isNaN(f) || Double.isNaN(direction)) {
  3148.             return Float.NaN;
  3149.         } else if (f == direction) {
  3150.             return (float) direction;
  3151.         } else if (Float.isInfinite(f)) {
  3152.             return (f < 0f) ? -Float.MAX_VALUE : Float.MAX_VALUE;
  3153.         } else if (f == 0f) {
  3154.             return (direction < 0) ? -Float.MIN_VALUE : Float.MIN_VALUE;
  3155.         }
  3156.         // special cases MAX_VALUE to infinity and  MIN_VALUE to 0
  3157.         // are handled just as normal numbers

  3158.         final int bits = Float.floatToIntBits(f);
  3159.         final int sign = bits & 0x80000000;
  3160.         if ((direction < f) ^ (sign == 0)) {
  3161.             return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) + 1));
  3162.         } else {
  3163.             return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) - 1));
  3164.         }

  3165.     }

  3166.     /** Get the largest whole number smaller than x.
  3167.      * @param x number from which floor is requested
  3168.      * @return a double number f such that f is an integer f &lt;= x &lt; f + 1.0
  3169.      */
  3170.     public static double floor(double x) {
  3171.         long y;

  3172.         if (Double.isNaN(x)) {
  3173.             return x;
  3174.         }

  3175.         if (x >= TWO_POWER_52 || x <= -TWO_POWER_52) {
  3176.             return x;
  3177.         }

  3178.         y = (long) x;
  3179.         if (x < 0 && y != x) {
  3180.             y--;
  3181.         }

  3182.         if (y == 0) {
  3183.             return x*y;
  3184.         }

  3185.         return y;
  3186.     }

  3187.     /** Get the smallest whole number larger than x.
  3188.      * @param x number from which ceil is requested
  3189.      * @return a double number c such that c is an integer c - 1.0 &lt; x &lt;= c
  3190.      */
  3191.     public static double ceil(double x) {
  3192.         double y;

  3193.         if (Double.isNaN(x)) {
  3194.             return x;
  3195.         }

  3196.         y = floor(x);
  3197.         if (y == x) {
  3198.             return y;
  3199.         }

  3200.         y += 1.0;

  3201.         if (y == 0) {
  3202.             return x*y;
  3203.         }

  3204.         return y;
  3205.     }

  3206.     /** Get the whole number that is the nearest to x, or the even one if x is exactly half way between two integers.
  3207.      * @param x number from which nearest whole number is requested
  3208.      * @return a double number r such that r is an integer r - 0.5 &lt;= x &lt;= r + 0.5
  3209.      */
  3210.     public static double rint(double x) {
  3211.         double y = floor(x);
  3212.         double d = x - y;

  3213.         if (d > 0.5) {
  3214.             if (y == -1.0) {
  3215.                 return -0.0; // Preserve sign of operand
  3216.             }
  3217.             return y+1.0;
  3218.         }
  3219.         if (d < 0.5) {
  3220.             return y;
  3221.         }

  3222.         /* half way, round to even */
  3223.         long z = (long) y;
  3224.         return (z & 1) == 0 ? y : y + 1.0;
  3225.     }

  3226.     /** Get the closest long to x.
  3227.      * @param x number from which closest long is requested
  3228.      * @return closest long to x
  3229.      */
  3230.     public static long round(double x) {
  3231.         final long bits = Double.doubleToRawLongBits(x);
  3232.         final int biasedExp = ((int)(bits>>52)) & 0x7ff;
  3233.         // Shift to get rid of bits past comma except first one: will need to
  3234.         // 1-shift to the right to end up with correct magnitude.
  3235.         final int shift = (52 - 1 + Double.MAX_EXPONENT) - biasedExp;
  3236.         if ((shift & -64) == 0) {
  3237.             // shift in [0,63], so unbiased exp in [-12,51].
  3238.             long extendedMantissa = 0x0010000000000000L | (bits & 0x000fffffffffffffL);
  3239.             if (bits < 0) {
  3240.                 extendedMantissa = -extendedMantissa;
  3241.             }
  3242.             // If value is positive and first bit past comma is 0, rounding
  3243.             // to lower integer, else to upper one, which is what "+1" and
  3244.             // then ">>1" do.
  3245.             return ((extendedMantissa >> shift) + 1L) >> 1;
  3246.         } else {
  3247.             // +-Infinity, NaN, or a mathematical integer.
  3248.             return (long) x;
  3249.         }
  3250.     }

  3251.     /** Get the closest int to x.
  3252.      * @param x number from which closest int is requested
  3253.      * @return closest int to x
  3254.      */
  3255.     public static int round(final float x) {
  3256.         final int bits = Float.floatToRawIntBits(x);
  3257.         final int biasedExp = (bits>>23) & 0xff;
  3258.         // Shift to get rid of bits past comma except first one: will need to
  3259.         // 1-shift to the right to end up with correct magnitude.
  3260.         final int shift = (23 - 1 + Float.MAX_EXPONENT) - biasedExp;
  3261.         if ((shift & -32) == 0) {
  3262.             // shift in [0,31], so unbiased exp in [-9,22].
  3263.             int extendedMantissa = 0x00800000 | (bits & 0x007fffff);
  3264.             if (bits < 0) {
  3265.                 extendedMantissa = -extendedMantissa;
  3266.             }
  3267.             // If value is positive and first bit past comma is 0, rounding
  3268.             // to lower integer, else to upper one, which is what "+1" and
  3269.             // then ">>1" do.
  3270.             return ((extendedMantissa >> shift) + 1) >> 1;
  3271.         } else {
  3272.             // +-Infinity, NaN, or a mathematical integer.
  3273.             return (int) x;
  3274.         }
  3275.     }

  3276.     /** Compute the minimum of two values
  3277.      * @param a first value
  3278.      * @param b second value
  3279.      * @return a if a is lesser or equal to b, b otherwise
  3280.      */
  3281.     public static int min(final int a, final int b) {
  3282.         return (a <= b) ? a : b;
  3283.     }

  3284.     /** Compute the minimum of two values
  3285.      * @param a first value
  3286.      * @param b second value
  3287.      * @return a if a is lesser or equal to b, b otherwise
  3288.      */
  3289.     public static long min(final long a, final long b) {
  3290.         return (a <= b) ? a : b;
  3291.     }

  3292.     /** Compute the minimum of two values
  3293.      * @param a first value
  3294.      * @param b second value
  3295.      * @return a if a is lesser or equal to b, b otherwise
  3296.      */
  3297.     public static float min(final float a, final float b) {
  3298.         if (a > b) {
  3299.             return b;
  3300.         }
  3301.         if (a < b) {
  3302.             return a;
  3303.         }
  3304.         /* if either arg is NaN, return NaN */
  3305.         if (a != b) {
  3306.             return Float.NaN;
  3307.         }
  3308.         /* min(+0.0,-0.0) == -0.0 */
  3309.         /* 0x80000000 == Float.floatToRawIntBits(-0.0d) */
  3310.         int bits = Float.floatToRawIntBits(a);
  3311.         if (bits == 0x80000000) {
  3312.             return a;
  3313.         }
  3314.         return b;
  3315.     }

  3316.     /** Compute the minimum of two values
  3317.      * @param a first value
  3318.      * @param b second value
  3319.      * @return a if a is lesser or equal to b, b otherwise
  3320.      */
  3321.     public static double min(final double a, final double b) {
  3322.         if (a > b) {
  3323.             return b;
  3324.         }
  3325.         if (a < b) {
  3326.             return a;
  3327.         }
  3328.         /* if either arg is NaN, return NaN */
  3329.         if (a != b) {
  3330.             return Double.NaN;
  3331.         }
  3332.         /* min(+0.0,-0.0) == -0.0 */
  3333.         /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */
  3334.         long bits = Double.doubleToRawLongBits(a);
  3335.         if (bits == 0x8000000000000000L) {
  3336.             return a;
  3337.         }
  3338.         return b;
  3339.     }

  3340.     /** Compute the maximum of two values
  3341.      * @param a first value
  3342.      * @param b second value
  3343.      * @return b if a is lesser or equal to b, a otherwise
  3344.      */
  3345.     public static int max(final int a, final int b) {
  3346.         return (a <= b) ? b : a;
  3347.     }

  3348.     /** Compute the maximum of two values
  3349.      * @param a first value
  3350.      * @param b second value
  3351.      * @return b if a is lesser or equal to b, a otherwise
  3352.      */
  3353.     public static long max(final long a, final long b) {
  3354.         return (a <= b) ? b : a;
  3355.     }

  3356.     /** Compute the maximum of two values
  3357.      * @param a first value
  3358.      * @param b second value
  3359.      * @return b if a is lesser or equal to b, a otherwise
  3360.      */
  3361.     public static float max(final float a, final float b) {
  3362.         if (a > b) {
  3363.             return a;
  3364.         }
  3365.         if (a < b) {
  3366.             return b;
  3367.         }
  3368.         /* if either arg is NaN, return NaN */
  3369.         if (a != b) {
  3370.             return Float.NaN;
  3371.         }
  3372.         /* min(+0.0,-0.0) == -0.0 */
  3373.         /* 0x80000000 == Float.floatToRawIntBits(-0.0d) */
  3374.         int bits = Float.floatToRawIntBits(a);
  3375.         if (bits == 0x80000000) {
  3376.             return b;
  3377.         }
  3378.         return a;
  3379.     }

  3380.     /** Compute the maximum of two values
  3381.      * @param a first value
  3382.      * @param b second value
  3383.      * @return b if a is lesser or equal to b, a otherwise
  3384.      */
  3385.     public static double max(final double a, final double b) {
  3386.         if (a > b) {
  3387.             return a;
  3388.         }
  3389.         if (a < b) {
  3390.             return b;
  3391.         }
  3392.         /* if either arg is NaN, return NaN */
  3393.         if (a != b) {
  3394.             return Double.NaN;
  3395.         }
  3396.         /* min(+0.0,-0.0) == -0.0 */
  3397.         /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */
  3398.         long bits = Double.doubleToRawLongBits(a);
  3399.         if (bits == 0x8000000000000000L) {
  3400.             return b;
  3401.         }
  3402.         return a;
  3403.     }

  3404.     /**
  3405.      * Returns the hypotenuse of a triangle with sides {@code x} and {@code y}
  3406.      * - sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)<br>
  3407.      * avoiding intermediate overflow or underflow.
  3408.      *
  3409.      * <ul>
  3410.      * <li> If either argument is infinite, then the result is positive infinity.</li>
  3411.      * <li> else, if either argument is NaN then the result is NaN.</li>
  3412.      * </ul>
  3413.      *
  3414.      * @param x a value
  3415.      * @param y a value
  3416.      * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
  3417.      */
  3418.     public static double hypot(final double x, final double y) {
  3419.         if (Double.isInfinite(x) || Double.isInfinite(y)) {
  3420.             return Double.POSITIVE_INFINITY;
  3421.         } else if (Double.isNaN(x) || Double.isNaN(y)) {
  3422.             return Double.NaN;
  3423.         } else {

  3424.             final int expX = getExponent(x);
  3425.             final int expY = getExponent(y);
  3426.             if (expX > expY + 27) {
  3427.                 // y is neglectible with respect to x
  3428.                 return abs(x);
  3429.             } else if (expY > expX + 27) {
  3430.                 // x is neglectible with respect to y
  3431.                 return abs(y);
  3432.             } else {

  3433.                 // find an intermediate scale to avoid both overflow and underflow
  3434.                 final int middleExp = (expX + expY) / 2;

  3435.                 // scale parameters without losing precision
  3436.                 final double scaledX = scalb(x, -middleExp);
  3437.                 final double scaledY = scalb(y, -middleExp);

  3438.                 // compute scaled hypotenuse
  3439.                 final double scaledH = sqrt(scaledX * scaledX + scaledY * scaledY);

  3440.                 // remove scaling
  3441.                 return scalb(scaledH, middleExp);

  3442.             }

  3443.         }
  3444.     }

  3445.     /**
  3446.      * Computes the remainder as prescribed by the IEEE 754 standard.
  3447.      * <p>
  3448.      * The remainder value is mathematically equal to {@code x - y*n}
  3449.      * where {@code n} is the mathematical integer closest to the exact mathematical value
  3450.      * of the quotient {@code x/y}.
  3451.      * If two mathematical integers are equally close to {@code x/y} then
  3452.      * {@code n} is the integer that is even.
  3453.      * </p>
  3454.      * <ul>
  3455.      * <li>If either operand is NaN, the result is NaN.</li>
  3456.      * <li>If the result is not NaN, the sign of the result equals the sign of the dividend.</li>
  3457.      * <li>If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.</li>
  3458.      * <li>If the dividend is finite and the divisor is an infinity, the result equals the dividend.</li>
  3459.      * <li>If the dividend is a zero and the divisor is finite, the result equals the dividend.</li>
  3460.      * </ul>
  3461.      * @param dividend the number to be divided
  3462.      * @param divisor the number by which to divide
  3463.      * @return the remainder, rounded
  3464.      */
  3465.     public static double IEEEremainder(final double dividend, final double divisor) {
  3466.         if (getExponent(dividend) == 1024 || getExponent(divisor) == 1024 || divisor == 0.0) {
  3467.             // we are in one of the special cases
  3468.             if (Double.isInfinite(divisor) && !Double.isInfinite(dividend)) {
  3469.                 return dividend;
  3470.             } else {
  3471.                 return Double.NaN;
  3472.             }
  3473.         } else {
  3474.             // we are in the general case
  3475.             final double n         = rint(dividend / divisor);
  3476.             final double remainder = Double.isInfinite(n) ? 0.0 : dividend - divisor * n;
  3477.             return (remainder == 0) ? copySign(remainder, dividend) : remainder;
  3478.         }
  3479.     }

  3480.     /** Convert a long to interger, detecting overflows
  3481.      * @param n number to convert to int
  3482.      * @return integer with same valie as n if no overflows occur
  3483.      * @exception MathRuntimeException if n cannot fit into an int
  3484.      */
  3485.     public static int toIntExact(final long n) throws MathRuntimeException {
  3486.         if (n < Integer.MIN_VALUE || n > Integer.MAX_VALUE) {
  3487.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW);
  3488.         }
  3489.         return (int) n;
  3490.     }

  3491.     /** Increment a number, detecting overflows.
  3492.      * @param n number to increment
  3493.      * @return n+1 if no overflows occur
  3494.      * @exception MathRuntimeException if an overflow occurs
  3495.      */
  3496.     public static int incrementExact(final int n) throws MathRuntimeException {

  3497.         if (n == Integer.MAX_VALUE) {
  3498.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_ADDITION, n, 1);
  3499.         }

  3500.         return n + 1;

  3501.     }

  3502.     /** Increment a number, detecting overflows.
  3503.      * @param n number to increment
  3504.      * @return n+1 if no overflows occur
  3505.      * @exception MathRuntimeException if an overflow occurs
  3506.      */
  3507.     public static long incrementExact(final long n) throws MathRuntimeException {

  3508.         if (n == Long.MAX_VALUE) {
  3509.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_ADDITION, n, 1);
  3510.         }

  3511.         return n + 1;

  3512.     }

  3513.     /** Decrement a number, detecting overflows.
  3514.      * @param n number to decrement
  3515.      * @return n-1 if no overflows occur
  3516.      * @exception MathRuntimeException if an overflow occurs
  3517.      */
  3518.     public static int decrementExact(final int n) throws MathRuntimeException {

  3519.         if (n == Integer.MIN_VALUE) {
  3520.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_SUBTRACTION, n, 1);
  3521.         }

  3522.         return n - 1;

  3523.     }

  3524.     /** Decrement a number, detecting overflows.
  3525.      * @param n number to decrement
  3526.      * @return n-1 if no overflows occur
  3527.      * @exception MathRuntimeException if an overflow occurs
  3528.      */
  3529.     public static long decrementExact(final long n) throws MathRuntimeException {

  3530.         if (n == Long.MIN_VALUE) {
  3531.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_SUBTRACTION, n, 1);
  3532.         }

  3533.         return n - 1;

  3534.     }

  3535.     /** Add two numbers, detecting overflows.
  3536.      * @param a first number to add
  3537.      * @param b second number to add
  3538.      * @return a+b if no overflows occur
  3539.      * @exception MathRuntimeException if an overflow occurs
  3540.      */
  3541.     public static int addExact(final int a, final int b) throws MathRuntimeException {

  3542.         // compute sum
  3543.         final int sum = a + b;

  3544.         // check for overflow
  3545.         if ((a ^ b) >= 0 && (sum ^ b) < 0) {
  3546.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_ADDITION, a, b);
  3547.         }

  3548.         return sum;

  3549.     }

  3550.     /** Add two numbers, detecting overflows.
  3551.      * @param a first number to add
  3552.      * @param b second number to add
  3553.      * @return a+b if no overflows occur
  3554.      * @exception MathRuntimeException if an overflow occurs
  3555.      */
  3556.     public static long addExact(final long a, final long b) throws MathRuntimeException {

  3557.         // compute sum
  3558.         final long sum = a + b;

  3559.         // check for overflow
  3560.         if ((a ^ b) >= 0 && (sum ^ b) < 0) {
  3561.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_ADDITION, a, b);
  3562.         }

  3563.         return sum;

  3564.     }

  3565.     /** Subtract two numbers, detecting overflows.
  3566.      * @param a first number
  3567.      * @param b second number to subtract from a
  3568.      * @return a-b if no overflows occur
  3569.      * @exception MathRuntimeException if an overflow occurs
  3570.      */
  3571.     public static int subtractExact(final int a, final int b) {

  3572.         // compute subtraction
  3573.         final int sub = a - b;

  3574.         // check for overflow
  3575.         if ((a ^ b) < 0 && (sub ^ b) >= 0) {
  3576.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_SUBTRACTION, a, b);
  3577.         }

  3578.         return sub;

  3579.     }

  3580.     /** Subtract two numbers, detecting overflows.
  3581.      * @param a first number
  3582.      * @param b second number to subtract from a
  3583.      * @return a-b if no overflows occur
  3584.      * @exception MathRuntimeException if an overflow occurs
  3585.      */
  3586.     public static long subtractExact(final long a, final long b) {

  3587.         // compute subtraction
  3588.         final long sub = a - b;

  3589.         // check for overflow
  3590.         if ((a ^ b) < 0 && (sub ^ b) >= 0) {
  3591.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_SUBTRACTION, a, b);
  3592.         }

  3593.         return sub;

  3594.     }

  3595.     /** Multiply two numbers, detecting overflows.
  3596.      * @param a first number to multiply
  3597.      * @param b second number to multiply
  3598.      * @return a*b if no overflows occur
  3599.      * @exception MathRuntimeException if an overflow occurs
  3600.      */
  3601.     public static int multiplyExact(final int a, final int b) {
  3602.         if (((b  >  0)  && (a > Integer.MAX_VALUE / b || a < Integer.MIN_VALUE / b)) ||
  3603.             ((b  < -1)  && (a > Integer.MIN_VALUE / b || a < Integer.MAX_VALUE / b)) ||
  3604.             ((b == -1)  && (a == Integer.MIN_VALUE))) {
  3605.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_MULTIPLICATION, a, b);
  3606.         }
  3607.         return a * b;
  3608.     }

  3609.     /** Multiply two numbers, detecting overflows.
  3610.      * @param a first number to multiply
  3611.      * @param b second number to multiply
  3612.      * @return a*b if no overflows occur
  3613.      * @exception MathRuntimeException if an overflow occurs
  3614.      * @since 1.3
  3615.      */
  3616.     public static long multiplyExact(final long a, final int b) {
  3617.         return multiplyExact(a, (long) b);
  3618.     }

  3619.     /** Multiply two numbers, detecting overflows.
  3620.      * @param a first number to multiply
  3621.      * @param b second number to multiply
  3622.      * @return a*b if no overflows occur
  3623.      * @exception MathRuntimeException if an overflow occurs
  3624.      */
  3625.     public static long multiplyExact(final long a, final long b) {
  3626.         if (((b  >  0l)  && (a > Long.MAX_VALUE / b || a < Long.MIN_VALUE / b)) ||
  3627.             ((b  < -1l)  && (a > Long.MIN_VALUE / b || a < Long.MAX_VALUE / b)) ||
  3628.             ((b == -1l)  && (a == Long.MIN_VALUE))) {
  3629.                 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_MULTIPLICATION, a, b);
  3630.             }
  3631.             return a * b;
  3632.     }

  3633.     /** Multiply two integers and give an exact result without overflow.
  3634.      * @param a first factor
  3635.      * @param b second factor
  3636.      * @return a * b exactly
  3637.      * @since 1.3
  3638.      */
  3639.     public static long multiplyFull(final int a, final int b) {
  3640.         return ((long) a) * ((long) b); // NOPMD - casts are intentional here
  3641.     }

  3642.     /** Multiply two long integers and give the 64 most significant bits of the result.
  3643.      * <p>
  3644.      * Beware that as Java primitive long are always considered to be signed, there are some
  3645.      * intermediate values {@code a} and {@code b} for which {@code a * b} exceeds {@code Long.MAX_VALUE}
  3646.      * but this method will still return 0l. This happens for example for {@code a = 2³¹} and
  3647.      * {@code b = 2³²} as {@code a * b = 2⁶³ = Long.MAX_VALUE + 1}, so it exceeds the max value
  3648.      * for a long, but still fits in 64 bits, so this method correctly returns 0l in this case,
  3649.      * but multiplication result would be considered negative (and in fact equal to {@code Long.MIN_VALUE}
  3650.      * </p>
  3651.      * @param a first factor
  3652.      * @param b second factor
  3653.      * @return a * b / 2<sup>64</sup>
  3654.      * @since 1.3
  3655.      */
  3656.     public static long multiplyHigh(final long a, final long b) {

  3657.         // all computations below are performed on unsigned numbers because we start
  3658.         // by using logical shifts (and not arithmetic shifts). We will therefore
  3659.         // need to take care of sign before returning
  3660.         // a negative long n between -2⁶³ and -1, interpreted as an unsigned long
  3661.         // corresponds to 2⁶⁴ + n (which is between 2⁶³ and 2⁶⁴-1)
  3662.         // so if this number is multiplied by p, what we really compute
  3663.         // is (2⁶⁴ + n) * p = 2⁶⁴ * p + n * p, therefore the part above 64 bits
  3664.         // will have an extra term p that we will need to remove
  3665.         final long tobeRemoved = ((a < 0) ? b : 0) + ((b < 0) ? a : 0);

  3666.         return unsignedMultiplyHigh(a, b) - tobeRemoved;

  3667.     }

  3668.     /** Multiply two long unsigned integers and give the 64 most significant bits of the unsigned result.
  3669.      * <p>
  3670.      * Beware that as Java primitive long are always considered to be signed, there are some
  3671.      * intermediate values {@code a} and {@code b} for which {@code a * b} exceeds {@code Long.MAX_VALUE}
  3672.      * but this method will still return 0l. This happens for example for {@code a = 2³¹} and
  3673.      * {@code b = 2³²} as {@code a * b = 2⁶³ = Long.MAX_VALUE + 1}, so it exceeds the max value
  3674.      * for a long, but still fits in 64 bits, so this method correctly returns 0l in this case,
  3675.      * but multiplication result would be considered negative (and in fact equal to {@code Long.MIN_VALUE}
  3676.      * </p>
  3677.      * @param a first factor
  3678.      * @param b second factor
  3679.      * @return a * b / 2<sup>64</sup>
  3680.      * @since 3.0
  3681.      */
  3682.     public static long unsignedMultiplyHigh(final long a, final long b) {

  3683.         // split numbers in two 32 bits parts
  3684.         final long aHigh  = a >>> 32;
  3685.         final long aLow   = a & 0xFFFFFFFFl;
  3686.         final long bHigh  = b >>> 32;
  3687.         final long bLow   = b & 0xFFFFFFFFl;

  3688.         // ab = aHigh * bHigh * 2⁶⁴ + (aHigh * bLow + aLow * bHigh) * 2³² + aLow * bLow
  3689.         final long hh     = aHigh * bHigh;
  3690.         final long hl1    = aHigh * bLow;
  3691.         final long hl2    = aLow  * bHigh;
  3692.         final long ll     = aLow  * bLow;

  3693.         // adds up everything in the above 64 bit part, taking care to avoid overflow
  3694.         final long hlHigh = (hl1 >>> 32) + (hl2 >>> 32);
  3695.         final long hlLow  = (hl1 & 0xFFFFFFFFl) + (hl2 & 0xFFFFFFFFl);
  3696.         final long carry  = (hlLow + (ll >>> 32)) >>> 32;

  3697.         return hh + hlHigh + carry;

  3698.     }

  3699.     /** Divide two integers, checking for overflow.
  3700.      * @param x dividend
  3701.      * @param y divisor
  3702.      * @return x / y
  3703.      * @exception MathRuntimeException if an overflow occurs
  3704.      * @since 3.0
  3705.      */
  3706.     public static int divideExact(final int x, final int y) {
  3707.         if (y == 0) {
  3708.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  3709.         }
  3710.         if (y == -1 && x == Integer.MIN_VALUE) {
  3711.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, x, y);
  3712.         }
  3713.         return x / y;
  3714.     }

  3715.     /** Divide two long integers, checking for overflow.
  3716.      * @param x dividend
  3717.      * @param y divisor
  3718.      * @return x / y
  3719.      * @exception MathRuntimeException if an overflow occurs
  3720.      * @since 3.0
  3721.      */
  3722.     public static long divideExact(final long x, final long y) {
  3723.         if (y == 0l) {
  3724.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  3725.         }
  3726.         if (y == -1l && x == Long.MIN_VALUE) {
  3727.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, x, y);
  3728.         }
  3729.         return x / y;
  3730.     }

  3731.     /** Finds q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}.
  3732.      * <p>
  3733.      * This methods returns the same value as integer division when
  3734.      * a and b are opposite signs, but returns a different value when
  3735.      * they are same (i.e. q is positive).
  3736.      *
  3737.      * @param a dividend
  3738.      * @param b divisor
  3739.      * @return q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}
  3740.      * @exception MathRuntimeException if b == 0
  3741.      * @since 3.0
  3742.      */
  3743.     public static int ceilDiv(final int a, final int b) throws MathRuntimeException {

  3744.         if (b == 0) {
  3745.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  3746.         }

  3747.         final int m = a % b;
  3748.         if ((a ^ b) < 0 || m == 0) {
  3749.             // a and b have opposite signs, or division is exact
  3750.             return a / b;
  3751.         } else {
  3752.             // a and b have same signs and division is not exact
  3753.             return (a / b) + 1;
  3754.         }

  3755.     }

  3756.     /** Finds q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}.
  3757.      * <p>
  3758.      * This methods returns the same value as integer division when
  3759.      * a and b are opposite signs, but returns a different value when
  3760.      * they are same (i.e. q is positive).
  3761.      *
  3762.      * @param a dividend
  3763.      * @param b divisor
  3764.      * @return q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}
  3765.      * @exception MathRuntimeException if b == 0 or if a == {@code Integer.MIN_VALUE} and b = -1
  3766.      * @since 3.0
  3767.      */
  3768.     public static int ceilDivExact(final int a, final int b) throws MathRuntimeException {

  3769.         if (a == Integer.MIN_VALUE && b == -1) {
  3770.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, a, b);
  3771.         }

  3772.         return ceilDiv(a, b);

  3773.     }

  3774.     /** Finds q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}.
  3775.      * <p>
  3776.      * This methods returns the same value as integer division when
  3777.      * a and b are opposite signs, but returns a different value when
  3778.      * they are same (i.e. q is positive).
  3779.      *
  3780.      * @param a dividend
  3781.      * @param b divisor
  3782.      * @return q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}
  3783.      * @exception MathRuntimeException if b == 0
  3784.      * @since 3.0
  3785.      */
  3786.     public static long ceilDiv(final long a, final long b) throws MathRuntimeException {

  3787.         if (b == 0l) {
  3788.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  3789.         }

  3790.         final long m = a % b;
  3791.         if ((a ^ b) < 0 || m == 0l) {
  3792.             // a and b have opposite signs, or division is exact
  3793.             return a / b;
  3794.         } else {
  3795.             // a and b have same signs and division is not exact
  3796.             return (a / b) + 1l;
  3797.         }

  3798.     }

  3799.     /** Finds q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}.
  3800.      * <p>
  3801.      * This methods returns the same value as integer division when
  3802.      * a and b are opposite signs, but returns a different value when
  3803.      * they are same (i.e. q is positive).
  3804.      *
  3805.      * @param a dividend
  3806.      * @param b divisor
  3807.      * @return q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}
  3808.      * @exception MathRuntimeException if b == 0 or if a == {@code Long.MIN_VALUE} and b = -1
  3809.      * @since 3.0
  3810.      */
  3811.     public static long ceilDivExact(final long a, final long b) throws MathRuntimeException {

  3812.         if (a == Long.MIN_VALUE && b == -1l) {
  3813.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, a, b);
  3814.         }

  3815.         return ceilDiv(a, b);

  3816.     }

  3817.     /** Finds q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}.
  3818.      * <p>
  3819.      * This methods returns the same value as integer division when
  3820.      * a and b are opposite signs, but returns a different value when
  3821.      * they are same (i.e. q is positive).
  3822.      *
  3823.      * @param a dividend
  3824.      * @param b divisor
  3825.      * @return q such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}
  3826.      * @exception MathRuntimeException if b == 0
  3827.      * @since 3.0
  3828.      */
  3829.     public static long ceilDiv(final long a, final int b) throws MathRuntimeException {
  3830.         return ceilDiv(a, (long) b);
  3831.     }

  3832.     /** Finds r such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}.
  3833.      * <p>
  3834.      * This methods returns the same value as integer modulo when
  3835.      * a and b are opposite signs, but returns a different value when
  3836.      * they are same (i.e. q is positive).
  3837.      *
  3838.      * @param a dividend
  3839.      * @param b divisor
  3840.      * @return r such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}
  3841.      * @exception MathRuntimeException if b == 0
  3842.      * @since 3.0
  3843.      */
  3844.     public static int ceilMod(final int a, final int b) throws MathRuntimeException {

  3845.         if (b == 0) {
  3846.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  3847.         }

  3848.         final int m = a % b;
  3849.         if ((a ^ b) < 0 || m == 0) {
  3850.             // a and b have opposite signs, or division is exact
  3851.             return m;
  3852.         } else {
  3853.             // a and b have same signs and division is not exact
  3854.             return m - b;
  3855.         }

  3856.     }

  3857.     /** Finds r such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}.
  3858.      * <p>
  3859.      * This methods returns the same value as integer modulo when
  3860.      * a and b are opposite signs, but returns a different value when
  3861.      * they are same (i.e. q is positive).
  3862.      *
  3863.      * @param a dividend
  3864.      * @param b divisor
  3865.      * @return r such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}
  3866.      * @exception MathRuntimeException if b == 0
  3867.      * @since 3.0
  3868.      */
  3869.     public static int ceilMod(final long a, final int b) throws MathRuntimeException {
  3870.         return (int) ceilMod(a, (long) b);
  3871.     }

  3872.     /** Finds r such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}.
  3873.      * <p>
  3874.      * This methods returns the same value as integer modulo when
  3875.      * a and b are opposite signs, but returns a different value when
  3876.      * they are same (i.e. q is positive).
  3877.      *
  3878.      * @param a dividend
  3879.      * @param b divisor
  3880.      * @return r such that {@code a = q b + r} with {@code b < r <= 0} if {@code b > 0} and {@code 0 <= r < b} if {@code  b < 0}
  3881.      * @exception MathRuntimeException if b == 0
  3882.      * @since 3.0
  3883.      */
  3884.     public static long ceilMod(final long a, final long b) throws MathRuntimeException {

  3885.         if (b == 0l) {
  3886.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  3887.         }

  3888.         final long m = a % b;
  3889.         if ((a ^ b) < 0l || m == 0l) {
  3890.             // a and b have opposite signs, or division is exact
  3891.             return m;
  3892.         } else {
  3893.             // a and b have same signs and division is not exact
  3894.             return m - b;
  3895.         }

  3896.     }

  3897.     /** Finds q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code  b < 0}.
  3898.      * <p>
  3899.      * This methods returns the same value as integer division when
  3900.      * a and b are same signs, but returns a different value when
  3901.      * they are opposite (i.e. q is negative).
  3902.      *
  3903.      * @param a dividend
  3904.      * @param b divisor
  3905.      * @return q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code  b < 0}
  3906.      * @exception MathRuntimeException if b == 0
  3907.      * @see #floorMod(int, int)
  3908.      */
  3909.     public static int floorDiv(final int a, final int b) throws MathRuntimeException {

  3910.         if (b == 0) {
  3911.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  3912.         }

  3913.         final int m = a % b;
  3914.         if ((a ^ b) >= 0 || m == 0) {
  3915.             // a and b have same sign, or division is exact
  3916.             return a / b;
  3917.         } else {
  3918.             // a and b have opposite signs and division is not exact
  3919.             return (a / b) - 1;
  3920.         }

  3921.     }

  3922.     /** Finds q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code  b < 0}.
  3923.      * <p>
  3924.      * This methods returns the same value as integer division when
  3925.      * a and b are same signs, but returns a different value when
  3926.      * they are opposite (i.e. q is negative).
  3927.      *
  3928.      * @param a dividend
  3929.      * @param b divisor
  3930.      * @return q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code  b < 0}
  3931.      * @exception MathRuntimeException if b == 0 or if a == {@code Integer.MIN_VALUE} and b = -1
  3932.      * @see #floorMod(int, int)
  3933.      * @since 3.0
  3934.      */
  3935.     public static int floorDivExact(final int a, final int b) throws MathRuntimeException {

  3936.         if (a == Integer.MIN_VALUE && b == -1) {
  3937.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, a, b);
  3938.         }

  3939.         return floorDiv(a, b);

  3940.     }

  3941.     /** Finds q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}.
  3942.      * <p>
  3943.      * This methods returns the same value as integer division when
  3944.      * a and b are same signs, but returns a different value when
  3945.      * they are opposite (i.e. q is negative).
  3946.      *
  3947.      * @param a dividend
  3948.      * @param b divisor
  3949.      * @return q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}
  3950.      * @exception MathRuntimeException if b == 0
  3951.      * @see #floorMod(long, int)
  3952.      * @since 1.3
  3953.      */
  3954.     public static long floorDiv(final long a, final int b) throws MathRuntimeException {
  3955.         return floorDiv(a, (long) b);
  3956.     }

  3957.     /** Finds q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}.
  3958.      * <p>
  3959.      * This methods returns the same value as integer division when
  3960.      * a and b are same signs, but returns a different value when
  3961.      * they are opposite (i.e. q is negative).
  3962.      *
  3963.      * @param a dividend
  3964.      * @param b divisor
  3965.      * @return q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}
  3966.      * @exception MathRuntimeException if b == 0
  3967.      * @see #floorMod(long, long)
  3968.      */
  3969.     public static long floorDiv(final long a, final long b) throws MathRuntimeException {

  3970.         if (b == 0l) {
  3971.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  3972.         }

  3973.         final long m = a % b;
  3974.         if ((a ^ b) >= 0l || m == 0l) {
  3975.             // a and b have same sign, or division is exact
  3976.             return a / b;
  3977.         } else {
  3978.             // a and b have opposite signs and division is not exact
  3979.             return (a / b) - 1l;
  3980.         }

  3981.     }

  3982.     /** Finds q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}.
  3983.      * <p>
  3984.      * This methods returns the same value as integer division when
  3985.      * a and b are same signs, but returns a different value when
  3986.      * they are opposite (i.e. q is negative).
  3987.      *
  3988.      * @param a dividend
  3989.      * @param b divisor
  3990.      * @return q such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}
  3991.      * @exception MathRuntimeException if b == 0 or if a == {@code Long.MIN_VALUE} and b = -1
  3992.      * @see #floorMod(long, long)
  3993.      * @since 3.0
  3994.      */
  3995.     public static long floorDivExact(final long a, final long b) throws MathRuntimeException {

  3996.         if (a == Long.MIN_VALUE && b == -1l) {
  3997.             throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, a, b);
  3998.         }

  3999.         return floorDiv(a, b);

  4000.     }

  4001.     /** Finds r such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}.
  4002.      * <p>
  4003.      * This methods returns the same value as integer modulo when
  4004.      * a and b are same signs, but returns a different value when
  4005.      * they are opposite (i.e. q is negative).
  4006.      * </p>
  4007.      * @param a dividend
  4008.      * @param b divisor
  4009.      * @return r such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}
  4010.      * @exception MathRuntimeException if b == 0
  4011.      * @see #floorDiv(int, int)
  4012.      */
  4013.     public static int floorMod(final int a, final int b) throws MathRuntimeException {

  4014.         if (b == 0) {
  4015.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  4016.         }

  4017.         final int m = a % b;
  4018.         if ((a ^ b) >= 0 || m == 0) {
  4019.             // a and b have same sign, or division is exact
  4020.             return m;
  4021.         } else {
  4022.             // a and b have opposite signs and division is not exact
  4023.             return b + m;
  4024.         }

  4025.     }

  4026.     /** Finds r such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}.
  4027.      * <p>
  4028.      * This methods returns the same value as integer modulo when
  4029.      * a and b are same signs, but returns a different value when
  4030.      * they are opposite (i.e. q is negative).
  4031.      * </p>
  4032.      * @param a dividend
  4033.      * @param b divisor
  4034.      * @return r such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}
  4035.      * @exception MathRuntimeException if b == 0
  4036.      * @see #floorDiv(long, int)
  4037.      * @since 1.3
  4038.      */
  4039.     public static int floorMod(final long a, final int b) {
  4040.         return (int) floorMod(a, (long) b);
  4041.     }

  4042.     /** Finds r such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}.
  4043.      * <p>
  4044.      * This methods returns the same value as integer modulo when
  4045.      * a and b are same signs, but returns a different value when
  4046.      * they are opposite (i.e. q is negative).
  4047.      * </p>
  4048.      * @param a dividend
  4049.      * @param b divisor
  4050.      * @return r such that {@code a = q b + r} with {@code 0 <= r < b} if {@code b > 0} and {@code b < r <= 0} if {@code b < 0}
  4051.      * @exception MathRuntimeException if b == 0
  4052.      * @see #floorDiv(long, long)
  4053.      */
  4054.     public static long floorMod(final long a, final long b) {

  4055.         if (b == 0l) {
  4056.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  4057.         }

  4058.         final long m = a % b;
  4059.         if ((a ^ b) >= 0l || m == 0l) {
  4060.             // a and b have same sign, or division is exact
  4061.             return m;
  4062.         } else {
  4063.             // a and b have opposite signs and division is not exact
  4064.             return b + m;
  4065.         }

  4066.     }

  4067.     /**
  4068.      * Returns the first argument with the sign of the second argument.
  4069.      * A NaN {@code sign} argument is treated as positive.
  4070.      *
  4071.      * @param magnitude the value to return
  4072.      * @param sign the sign for the returned value
  4073.      * @return the magnitude with the same sign as the {@code sign} argument
  4074.      */
  4075.     public static double copySign(double magnitude, double sign){
  4076.         // The highest order bit is going to be zero if the
  4077.         // highest order bit of m and s is the same and one otherwise.
  4078.         // So (m^s) will be positive if both m and s have the same sign
  4079.         // and negative otherwise.
  4080.         final long m = Double.doubleToRawLongBits(magnitude); // don't care about NaN
  4081.         final long s = Double.doubleToRawLongBits(sign);
  4082.         if ((m ^ s) >= 0) {
  4083.             return magnitude;
  4084.         }
  4085.         return -magnitude; // flip sign
  4086.     }

  4087.     /**
  4088.      * Returns the first argument with the sign of the second argument.
  4089.      * A NaN {@code sign} argument is treated as positive.
  4090.      *
  4091.      * @param magnitude the value to return
  4092.      * @param sign the sign for the returned value
  4093.      * @return the magnitude with the same sign as the {@code sign} argument
  4094.      */
  4095.     public static float copySign(float magnitude, float sign){
  4096.         // The highest order bit is going to be zero if the
  4097.         // highest order bit of m and s is the same and one otherwise.
  4098.         // So (m^s) will be positive if both m and s have the same sign
  4099.         // and negative otherwise.
  4100.         final int m = Float.floatToRawIntBits(magnitude);
  4101.         final int s = Float.floatToRawIntBits(sign);
  4102.         if ((m ^ s) >= 0) {
  4103.             return magnitude;
  4104.         }
  4105.         return -magnitude; // flip sign
  4106.     }

  4107.     /**
  4108.      * Return the exponent of a double number, removing the bias.
  4109.      * <p>
  4110.      * For double numbers of the form 2<sup>x</sup>, the unbiased
  4111.      * exponent is exactly x.
  4112.      * </p>
  4113.      * @param d number from which exponent is requested
  4114.      * @return exponent for d in IEEE754 representation, without bias
  4115.      */
  4116.     public static int getExponent(final double d) {
  4117.         // NaN and Infinite will return 1024 anyhow so can use raw bits
  4118.         return (int) ((Double.doubleToRawLongBits(d) >>> 52) & 0x7ff) - 1023;
  4119.     }

  4120.     /**
  4121.      * Return the exponent of a float number, removing the bias.
  4122.      * <p>
  4123.      * For float numbers of the form 2<sup>x</sup>, the unbiased
  4124.      * exponent is exactly x.
  4125.      * </p>
  4126.      * @param f number from which exponent is requested
  4127.      * @return exponent for d in IEEE754 representation, without bias
  4128.      */
  4129.     public static int getExponent(final float f) {
  4130.         // NaN and Infinite will return the same exponent anyhow so can use raw bits
  4131.         return ((Float.floatToRawIntBits(f) >>> 23) & 0xff) - 127;
  4132.     }

  4133.     /** Compute Fused-multiply-add operation a * b + c.
  4134.      * <p>
  4135.      * This method was introduced in the regular {@code Math} and {@code StrictMath}
  4136.      * methods with Java 9, and then added to Hipparchus for consistency. However,
  4137.      * a more general method was available in Hipparchus that also allow to repeat
  4138.      * this computation across several terms: {@link MathArrays#linearCombination(double[], double[])}.
  4139.      * The linear combination method should probably be preferred in most cases.
  4140.      * </p>
  4141.      * @param a first factor
  4142.      * @param b second factor
  4143.      * @param c additive term
  4144.      * @return a * b + c, using extended precision in the multiplication
  4145.      * @see MathArrays#linearCombination(double[], double[])
  4146.      * @see MathArrays#linearCombination(double, double, double, double)
  4147.      * @see MathArrays#linearCombination(double, double, double, double, double, double)
  4148.      * @see MathArrays#linearCombination(double, double, double, double, double, double, double, double)
  4149.      * @since 1.3
  4150.      */
  4151.     public static double fma(final double a, final double b, final double c) {
  4152.         return MathArrays.linearCombination(a, b, 1.0, c);
  4153.     }

  4154.     /** Compute Fused-multiply-add operation a * b + c.
  4155.      * <p>
  4156.      * This method was introduced in the regular {@code Math} and {@code StrictMath}
  4157.      * methods with Java 9, and then added to Hipparchus for consistency. However,
  4158.      * a more general method was available in Hipparchus that also allow to repeat
  4159.      * this computation across several terms: {@link MathArrays#linearCombination(double[], double[])}.
  4160.      * The linear combination method should probably be preferred in most cases.
  4161.      * </p>
  4162.      * @param a first factor
  4163.      * @param b second factor
  4164.      * @param c additive term
  4165.      * @return a * b + c, using extended precision in the multiplication
  4166.      * @see MathArrays#linearCombination(double[], double[])
  4167.      * @see MathArrays#linearCombination(double, double, double, double)
  4168.      * @see MathArrays#linearCombination(double, double, double, double, double, double)
  4169.      * @see MathArrays#linearCombination(double, double, double, double, double, double, double, double)
  4170.      */
  4171.     public static float fma(final float a, final float b, final float c) {
  4172.         return (float) MathArrays.linearCombination(a, b, 1.0, c);
  4173.     }

  4174.     /** Compute the square root of a number.
  4175.      * @param a number on which evaluation is done
  4176.      * @param <T> the type of the field element
  4177.      * @return square root of a
  4178.      * @since 1.3
  4179.      */
  4180.     public static <T extends CalculusFieldElement<T>> T sqrt(final T a) {
  4181.         return a.sqrt();
  4182.     }

  4183.     /** Compute the hyperbolic cosine of a number.
  4184.      * @param x number on which evaluation is done
  4185.      * @param <T> the type of the field element
  4186.      * @return hyperbolic cosine of x
  4187.      * @since 1.3
  4188.      */
  4189.     public static <T extends CalculusFieldElement<T>> T cosh(final T x) {
  4190.         return x.cosh();
  4191.     }

  4192.     /** Compute the hyperbolic sine of a number.
  4193.      * @param x number on which evaluation is done
  4194.      * @param <T> the type of the field element
  4195.      * @return hyperbolic sine of x
  4196.      * @since 1.3
  4197.      */
  4198.     public static <T extends CalculusFieldElement<T>> T sinh(final T x) {
  4199.         return x.sinh();
  4200.     }

  4201.     /** Compute the hyperbolic tangent of a number.
  4202.      * @param x number on which evaluation is done
  4203.      * @param <T> the type of the field element
  4204.      * @return hyperbolic tangent of x
  4205.      * @since 1.3
  4206.      */
  4207.     public static <T extends CalculusFieldElement<T>> T tanh(final T x) {
  4208.         return x.tanh();
  4209.     }

  4210.     /** Compute the inverse hyperbolic cosine of a number.
  4211.      * @param a number on which evaluation is done
  4212.      * @param <T> the type of the field element
  4213.      * @return inverse hyperbolic cosine of a
  4214.      * @since 1.3
  4215.      */
  4216.     public static <T extends CalculusFieldElement<T>> T acosh(final T a) {
  4217.         return a.acosh();
  4218.     }

  4219.     /** Compute the inverse hyperbolic sine of a number.
  4220.      * @param a number on which evaluation is done
  4221.      * @param <T> the type of the field element
  4222.      * @return inverse hyperbolic sine of a
  4223.      * @since 1.3
  4224.      */
  4225.     public static <T extends CalculusFieldElement<T>> T asinh(final T a) {
  4226.         return a.asinh();
  4227.     }

  4228.     /** Compute the inverse hyperbolic tangent of a number.
  4229.      * @param a number on which evaluation is done
  4230.      * @param <T> the type of the field element
  4231.      * @return inverse hyperbolic tangent of a
  4232.      * @since 1.3
  4233.      */
  4234.     public static <T extends CalculusFieldElement<T>> T atanh(final T a) {
  4235.         return a.atanh();
  4236.     }

  4237.     /** Compute the sign of a number.
  4238.      * The sign is -1 for negative numbers, +1 for positive numbers and 0 otherwise,
  4239.      * for Complex number, it is extended on the unit circle (equivalent to z/|z|,
  4240.      * with special handling for 0 and NaN)
  4241.      * @param a number on which evaluation is done
  4242.      * @param <T> the type of the field element
  4243.      * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
  4244.      * @since 2.0
  4245.      */
  4246.     public static <T extends CalculusFieldElement<T>> T sign(final T a) {
  4247.         return a.sign();
  4248.     }

  4249.     /**
  4250.      * Exponential function.
  4251.      *
  4252.      * Computes exp(x), function result is nearly rounded.   It will be correctly
  4253.      * rounded to the theoretical value for 99.9% of input values, otherwise it will
  4254.      * have a 1 ULP error.
  4255.      *
  4256.      * Method:
  4257.      *    Lookup intVal = exp(int(x))
  4258.      *    Lookup fracVal = exp(int(x-int(x) / 1024.0) * 1024.0 );
  4259.      *    Compute z as the exponential of the remaining bits by a polynomial minus one
  4260.      *    exp(x) = intVal * fracVal * (1 + z)
  4261.      *
  4262.      * Accuracy:
  4263.      *    Calculation is done with 63 bits of precision, so result should be correctly
  4264.      *    rounded for 99.9% of input values, with less than 1 ULP error otherwise.
  4265.      *
  4266.      * @param x   a double
  4267.      * @param <T> the type of the field element
  4268.      * @return double e<sup>x</sup>
  4269.      * @since 1.3
  4270.      */
  4271.     public static <T extends CalculusFieldElement<T>> T exp(final T x) {
  4272.         return x.exp();
  4273.     }

  4274.     /** Compute exp(x) - 1
  4275.      * @param x number to compute shifted exponential
  4276.      * @param <T> the type of the field element
  4277.      * @return exp(x) - 1
  4278.      * @since 1.3
  4279.      */
  4280.     public static <T extends CalculusFieldElement<T>> T expm1(final T x) {
  4281.         return x.expm1();
  4282.     }

  4283.     /**
  4284.      * Natural logarithm.
  4285.      *
  4286.      * @param x   a double
  4287.      * @param <T> the type of the field element
  4288.      * @return log(x)
  4289.      * @since 1.3
  4290.      */
  4291.     public static <T extends CalculusFieldElement<T>> T log(final T x) {
  4292.         return x.log();
  4293.     }

  4294.     /**
  4295.      * Computes log(1 + x).
  4296.      *
  4297.      * @param x Number.
  4298.      * @param <T> the type of the field element
  4299.      * @return {@code log(1 + x)}.
  4300.      * @since 1.3
  4301.      */
  4302.     public static <T extends CalculusFieldElement<T>> T log1p(final T x) {
  4303.         return x.log1p();
  4304.     }

  4305.     /** Compute the base 10 logarithm.
  4306.      * @param x a number
  4307.      * @param <T> the type of the field element
  4308.      * @return log10(x)
  4309.      * @since 1.3
  4310.      */
  4311.     public static <T extends CalculusFieldElement<T>> T log10(final T x) {
  4312.         return x.log10();
  4313.     }

  4314.     /**
  4315.      * Power function.  Compute x<sup>y</sup>.
  4316.      *
  4317.      * @param x   a double
  4318.      * @param y   a double
  4319.      * @param <T> the type of the field element
  4320.      * @return x<sup>y</sup>
  4321.      * @since 1.3
  4322.      */
  4323.     public static <T extends CalculusFieldElement<T>> T pow(final T x, final T y) {
  4324.         return x.pow(y);
  4325.     }

  4326.     /**
  4327.      * Power function.  Compute x<sup>y</sup>.
  4328.      *
  4329.      * @param x   a double
  4330.      * @param y   a double
  4331.      * @param <T> the type of the field element
  4332.      * @return x<sup>y</sup>
  4333.      * @since 1.7
  4334.      */
  4335.     public static <T extends CalculusFieldElement<T>> T pow(final T x, final double y) {
  4336.         return x.pow(y);
  4337.     }

  4338.     /**
  4339.      * Raise a double to an int power.
  4340.      *
  4341.      * @param d Number to raise.
  4342.      * @param e Exponent.
  4343.      * @param <T> the type of the field element
  4344.      * @return d<sup>e</sup>
  4345.      * @since 1.3
  4346.      */
  4347.     public static <T extends CalculusFieldElement<T>> T pow(T d, int e) {
  4348.         return d.pow(e);
  4349.     }

  4350.     /**
  4351.      * Sine function.
  4352.      *
  4353.      * @param x Argument.
  4354.      * @param <T> the type of the field element
  4355.      * @return sin(x)
  4356.      * @since 1.3
  4357.      */
  4358.     public static <T extends CalculusFieldElement<T>> T sin(final T x) {
  4359.         return x.sin();
  4360.     }

  4361.     /**
  4362.      * Cosine function.
  4363.      *
  4364.      * @param x Argument.
  4365.      * @param <T> the type of the field element
  4366.      * @return cos(x)
  4367.      * @since 1.3
  4368.      */
  4369.     public static <T extends CalculusFieldElement<T>> T cos(final T x) {
  4370.         return x.cos();
  4371.     }

  4372.     /**
  4373.      * Tangent function.
  4374.      *
  4375.      * @param x Argument.
  4376.      * @param <T> the type of the field element
  4377.      * @return tan(x)
  4378.      * @since 1.3
  4379.      */
  4380.     public static <T extends CalculusFieldElement<T>> T tan(final T x) {
  4381.         return x.tan();
  4382.     }

  4383.     /**
  4384.      * Arctangent function
  4385.      *  @param x a number
  4386.      * @param <T> the type of the field element
  4387.      *  @return atan(x)
  4388.      * @since 1.3
  4389.      */
  4390.     public static <T extends CalculusFieldElement<T>> T atan(final T x) {
  4391.         return x.atan();
  4392.     }

  4393.     /**
  4394.      * Two arguments arctangent function
  4395.      * @param y ordinate
  4396.      * @param x abscissa
  4397.      * @param <T> the type of the field element
  4398.      * @return phase angle of point (x,y) between {@code -PI} and {@code PI}
  4399.      * @since 1.3
  4400.      */
  4401.     public static <T extends CalculusFieldElement<T>> T atan2(final T y, final T x) {
  4402.         return y.atan2(x);
  4403.     }

  4404.     /** Compute the arc sine of a number.
  4405.      * @param x number on which evaluation is done
  4406.      * @param <T> the type of the field element
  4407.      * @return arc sine of x
  4408.      * @since 1.3
  4409.      */
  4410.     public static <T extends CalculusFieldElement<T>> T asin(final T x) {
  4411.         return x.asin();
  4412.     }

  4413.     /** Compute the arc cosine of a number.
  4414.      * @param x number on which evaluation is done
  4415.      * @param <T> the type of the field element
  4416.      * @return arc cosine of x
  4417.      * @since 1.3
  4418.      */
  4419.     public static <T extends CalculusFieldElement<T>> T acos(final T x) {
  4420.         return x.acos();
  4421.     }

  4422.     /** Compute the cubic root of a number.
  4423.      * @param x number on which evaluation is done
  4424.      * @param <T> the type of the field element
  4425.      * @return cubic root of x
  4426.      * @since 1.3
  4427.      */
  4428.     public static <T extends CalculusFieldElement<T>> T cbrt(final T x) {
  4429.         return x.cbrt();
  4430.     }

  4431.     /**
  4432.      * Norm.
  4433.      * @param x number from which norm is requested
  4434.      * @param <T> the type of the field element
  4435.      * @return norm(x)
  4436.      * @since 2.0
  4437.      */
  4438.     public static <T extends CalculusFieldElement<T>> double norm(final T x) {
  4439.         return x.norm();
  4440.     }

  4441.     /**
  4442.      * Absolute value.
  4443.      * @param x number from which absolute value is requested
  4444.      * @param <T> the type of the field element
  4445.      * @return abs(x)
  4446.      * @since 2.0
  4447.      */
  4448.     public static <T extends CalculusFieldElement<T>> T abs(final T x) {
  4449.         return x.abs();
  4450.     }

  4451.     /**
  4452.      *  Convert degrees to radians, with error of less than 0.5 ULP
  4453.      *  @param x angle in degrees
  4454.      *  @param <T> the type of the field element
  4455.      *  @return x converted into radians
  4456.      */
  4457.     public static <T extends CalculusFieldElement<T>> T toRadians(T x) {
  4458.         return x.toRadians();
  4459.     }

  4460.     /**
  4461.      *  Convert radians to degrees, with error of less than 0.5 ULP
  4462.      *  @param x angle in radians
  4463.      *  @param <T> the type of the field element
  4464.      *  @return x converted into degrees
  4465.      */
  4466.     public static <T extends CalculusFieldElement<T>> T toDegrees(T x) {
  4467.         return x.toDegrees();
  4468.     }

  4469.     /**
  4470.      * Multiply a double number by a power of 2.
  4471.      * @param d number to multiply
  4472.      * @param n power of 2
  4473.      * @param <T> the type of the field element
  4474.      * @return d &times; 2<sup>n</sup>
  4475.      * @since 1.3
  4476.      */
  4477.     public static <T extends CalculusFieldElement<T>> T scalb(final T d, final int n) {
  4478.         return d.scalb(n);
  4479.     }

  4480.     /**
  4481.      * Compute least significant bit (Unit in Last Position) for a number.
  4482.      * @param x number from which ulp is requested
  4483.      * @param <T> the type of the field element
  4484.      * @return ulp(x)
  4485.      * @since 2.0
  4486.      */
  4487.     public static <T extends CalculusFieldElement<T>> T ulp(final T x) {
  4488.         if (Double.isInfinite(x.getReal())) {
  4489.             return x.newInstance(Double.POSITIVE_INFINITY);
  4490.         }
  4491.         return x.ulp();
  4492.     }

  4493.     /** Get the largest whole number smaller than x.
  4494.      * @param x number from which floor is requested
  4495.      * @param <T> the type of the field element
  4496.      * @return a double number f such that f is an integer f &lt;= x &lt; f + 1.0
  4497.      * @since 1.3
  4498.      */
  4499.     public static <T extends CalculusFieldElement<T>> T floor(final T x) {
  4500.         return x.floor();
  4501.     }

  4502.     /** Get the smallest whole number larger than x.
  4503.      * @param x number from which ceil is requested
  4504.      * @param <T> the type of the field element
  4505.      * @return a double number c such that c is an integer c - 1.0 &lt; x &lt;= c
  4506.      * @since 1.3
  4507.      */
  4508.     public static <T extends CalculusFieldElement<T>> T ceil(final T x) {
  4509.         return x.ceil();
  4510.     }

  4511.     /** Get the whole number that is the nearest to x, or the even one if x is exactly half way between two integers.
  4512.      * @param x number from which nearest whole number is requested
  4513.      * @param <T> the type of the field element
  4514.      * @return a double number r such that r is an integer r - 0.5 &lt;= x &lt;= r + 0.5
  4515.      * @since 1.3
  4516.      */
  4517.     public static <T extends CalculusFieldElement<T>> T rint(final T x) {
  4518.         return x.rint();
  4519.     }

  4520.     /** Get the closest long to x.
  4521.      * @param x number from which closest long is requested
  4522.      * @param <T> the type of the field element
  4523.      * @return closest long to x
  4524.      * @since 1.3
  4525.      */
  4526.     public static <T extends CalculusFieldElement<T>> long round(final T x) {
  4527.         return x.round();
  4528.     }

  4529.     /** Compute the minimum of two values
  4530.      * @param a first value
  4531.      * @param b second value
  4532.      * @param <T> the type of the field element
  4533.      * @return a if a is lesser or equal to b, b otherwise
  4534.      * @since 1.3
  4535.      */
  4536.     public static <T extends CalculusFieldElement<T>> T min(final T a, final T b) {
  4537.         final double aR = a.getReal();
  4538.         final double bR = b.getReal();
  4539.         if (aR < bR) {
  4540.             return a;
  4541.         } else if (bR < aR) {
  4542.             return b;
  4543.         } else {
  4544.             // either the numbers are equal, or one of them is a NaN
  4545.             return Double.isNaN(aR) ? a : b;
  4546.         }
  4547.     }

  4548.     /** Compute the minimum of two values
  4549.      * @param a first value
  4550.      * @param b second value
  4551.      * @param <T> the type of the field element
  4552.      * @return a if a is lesser or equal to b, b otherwise
  4553.      * @since 1.3
  4554.      */
  4555.     public static <T extends CalculusFieldElement<T>> T min(final T a, final double b) {
  4556.         final double aR = a.getReal();
  4557.         if (aR < b) {
  4558.             return a;
  4559.         } else if (b < aR) {
  4560.             return a.getField().getZero().add(b);
  4561.         } else {
  4562.             // either the numbers are equal, or one of them is a NaN
  4563.             return Double.isNaN(aR) ? a : a.getField().getZero().add(b);
  4564.         }
  4565.     }

  4566.     /** Compute the maximum of two values
  4567.      * @param a first value
  4568.      * @param b second value
  4569.      * @param <T> the type of the field element
  4570.      * @return b if a is lesser or equal to b, a otherwise
  4571.      * @since 1.3
  4572.      */
  4573.     public static <T extends CalculusFieldElement<T>> T max(final T a, final T b) {
  4574.         final double aR = a.getReal();
  4575.         final double bR = b.getReal();
  4576.         if (aR < bR) {
  4577.             return b;
  4578.         } else if (bR < aR) {
  4579.             return a;
  4580.         } else {
  4581.             // either the numbers are equal, or one of them is a NaN
  4582.             return Double.isNaN(aR) ? a : b;
  4583.         }
  4584.     }

  4585.     /** Compute the maximum of two values
  4586.      * @param a first value
  4587.      * @param b second value
  4588.      * @param <T> the type of the field element
  4589.      * @return b if a is lesser or equal to b, a otherwise
  4590.      * @since 1.3
  4591.      */
  4592.     public static <T extends CalculusFieldElement<T>> T max(final T a, final double b) {
  4593.         final double aR = a.getReal();
  4594.         if (aR < b) {
  4595.             return a.getField().getZero().add(b);
  4596.         } else if (b < aR) {
  4597.             return a;
  4598.         } else {
  4599.             // either the numbers are equal, or one of them is a NaN
  4600.             return Double.isNaN(aR) ? a : a.getField().getZero().add(b);
  4601.         }
  4602.     }

  4603.     /**
  4604.      * Returns the hypotenuse of a triangle with sides {@code x} and {@code y}
  4605.      * - sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)<br>
  4606.      * avoiding intermediate overflow or underflow.
  4607.      *
  4608.      * <ul>
  4609.      * <li> If either argument is infinite, then the result is positive infinity.</li>
  4610.      * <li> else, if either argument is NaN then the result is NaN.</li>
  4611.      * </ul>
  4612.      *
  4613.      * @param x a value
  4614.      * @param y a value
  4615.      * @param <T> the type of the field element
  4616.      * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
  4617.      * @since 1.3
  4618.      */
  4619.     public static <T extends CalculusFieldElement<T>> T hypot(final T x, final T y) {
  4620.         return x.hypot(y);
  4621.     }

  4622.     /**
  4623.      * Computes the remainder as prescribed by the IEEE 754 standard.
  4624.      * <p>
  4625.      * The remainder value is mathematically equal to {@code x - y*n}
  4626.      * where {@code n} is the mathematical integer closest to the exact mathematical value
  4627.      * of the quotient {@code x/y}.
  4628.      * If two mathematical integers are equally close to {@code x/y} then
  4629.      * {@code n} is the integer that is even.
  4630.      * </p>
  4631.      * <ul>
  4632.      * <li>If either operand is NaN, the result is NaN.</li>
  4633.      * <li>If the result is not NaN, the sign of the result equals the sign of the dividend.</li>
  4634.      * <li>If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.</li>
  4635.      * <li>If the dividend is finite and the divisor is an infinity, the result equals the dividend.</li>
  4636.      * <li>If the dividend is a zero and the divisor is finite, the result equals the dividend.</li>
  4637.      * </ul>
  4638.      * @param dividend the number to be divided
  4639.      * @param divisor the number by which to divide
  4640.      * @param <T> the type of the field element
  4641.      * @return the remainder, rounded
  4642.      * @since 1.3
  4643.      */
  4644.     public static <T extends CalculusFieldElement<T>> T IEEEremainder(final T dividend, final double divisor) {
  4645.         return dividend.remainder(divisor);
  4646.     }

  4647.     /**
  4648.      * Computes the remainder as prescribed by the IEEE 754 standard.
  4649.      * <p>
  4650.      * The remainder value is mathematically equal to {@code x - y*n}
  4651.      * where {@code n} is the mathematical integer closest to the exact mathematical value
  4652.      * of the quotient {@code x/y}.
  4653.      * If two mathematical integers are equally close to {@code x/y} then
  4654.      * {@code n} is the integer that is even.
  4655.      * </p>
  4656.      * <ul>
  4657.      * <li>If either operand is NaN, the result is NaN.</li>
  4658.      * <li>If the result is not NaN, the sign of the result equals the sign of the dividend.</li>
  4659.      * <li>If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.</li>
  4660.      * <li>If the dividend is finite and the divisor is an infinity, the result equals the dividend.</li>
  4661.      * <li>If the dividend is a zero and the divisor is finite, the result equals the dividend.</li>
  4662.      * </ul>
  4663.      * @param dividend the number to be divided
  4664.      * @param divisor the number by which to divide
  4665.      * @param <T> the type of the field element
  4666.      * @return the remainder, rounded
  4667.      * @since 1.3
  4668.      */
  4669.     public static <T extends CalculusFieldElement<T>> T IEEEremainder(final T dividend, final T divisor) {
  4670.         return dividend.remainder(divisor);
  4671.     }

  4672.     /**
  4673.      * Returns the first argument with the sign of the second argument.
  4674.      * A NaN {@code sign} argument is treated as positive.
  4675.      *
  4676.      * @param magnitude the value to return
  4677.      * @param sign the sign for the returned value
  4678.      * @param <T> the type of the field element
  4679.      * @return the magnitude with the same sign as the {@code sign} argument
  4680.      * @since 1.3
  4681.      */
  4682.     public static <T extends CalculusFieldElement<T>> T copySign(T magnitude, T sign) {
  4683.         return magnitude.copySign(sign);
  4684.     }

  4685.     /**
  4686.      * Returns the first argument with the sign of the second argument.
  4687.      * A NaN {@code sign} argument is treated as positive.
  4688.      *
  4689.      * @param magnitude the value to return
  4690.      * @param sign the sign for the returned value
  4691.      * @param <T> the type of the field element
  4692.      * @return the magnitude with the same sign as the {@code sign} argument
  4693.      * @since 1.3
  4694.      */
  4695.     public static <T extends CalculusFieldElement<T>> T copySign(T magnitude, double sign) {
  4696.         return magnitude.copySign(sign);
  4697.     }

  4698. //    /**
  4699. //     * Print out contents of arrays, and check the length.
  4700. //     * <p>used to generate the preset arrays originally.</p>
  4701. //     * @param a unused
  4702. //     */
  4703. //    public static void main(String[] a) {
  4704. //        FastMathCalc.printarray(System.out, "EXP_INT_TABLE_A", EXP_INT_TABLE_LEN, ExpIntTable.EXP_INT_TABLE_A);
  4705. //        FastMathCalc.printarray(System.out, "EXP_INT_TABLE_B", EXP_INT_TABLE_LEN, ExpIntTable.EXP_INT_TABLE_B);
  4706. //        FastMathCalc.printarray(System.out, "EXP_FRAC_TABLE_A", EXP_FRAC_TABLE_LEN, ExpFracTable.EXP_FRAC_TABLE_A);
  4707. //        FastMathCalc.printarray(System.out, "EXP_FRAC_TABLE_B", EXP_FRAC_TABLE_LEN, ExpFracTable.EXP_FRAC_TABLE_B);
  4708. //        FastMathCalc.printarray(System.out, "LN_MANT",LN_MANT_LEN, lnMant.LN_MANT);
  4709. //        FastMathCalc.printarray(System.out, "SINE_TABLE_A", SINE_TABLE_LEN, SINE_TABLE_A);
  4710. //        FastMathCalc.printarray(System.out, "SINE_TABLE_B", SINE_TABLE_LEN, SINE_TABLE_B);
  4711. //        FastMathCalc.printarray(System.out, "COSINE_TABLE_A", SINE_TABLE_LEN, COSINE_TABLE_A);
  4712. //        FastMathCalc.printarray(System.out, "COSINE_TABLE_B", SINE_TABLE_LEN, COSINE_TABLE_B);
  4713. //        FastMathCalc.printarray(System.out, "TANGENT_TABLE_A", SINE_TABLE_LEN, TANGENT_TABLE_A);
  4714. //        FastMathCalc.printarray(System.out, "TANGENT_TABLE_B", SINE_TABLE_LEN, TANGENT_TABLE_B);
  4715. //    }

  4716.     /** Enclose large data table in nested static class so it's only loaded on first access. */
  4717.     private static class ExpIntTable {
  4718.         /** Exponential evaluated at integer values,
  4719.          * exp(x) =  expIntTableA[x + EXP_INT_TABLE_MAX_INDEX] + expIntTableB[x+EXP_INT_TABLE_MAX_INDEX].
  4720.          */
  4721.         private static final double[] EXP_INT_TABLE_A;
  4722.         /** Exponential evaluated at integer values,
  4723.          * exp(x) =  expIntTableA[x + EXP_INT_TABLE_MAX_INDEX] + expIntTableB[x+EXP_INT_TABLE_MAX_INDEX]
  4724.          */
  4725.         private static final double[] EXP_INT_TABLE_B;

  4726.         static {
  4727.             if (RECOMPUTE_TABLES_AT_RUNTIME) {
  4728.                 EXP_INT_TABLE_A = new double[EXP_INT_TABLE_LEN];
  4729.                 EXP_INT_TABLE_B = new double[EXP_INT_TABLE_LEN];

  4730.                 final double[] tmp = new double[2];
  4731.                 final double[] recip = new double[2];

  4732.                 // Populate expIntTable
  4733.                 for (int i = 0; i < EXP_INT_TABLE_MAX_INDEX; i++) {
  4734.                     FastMathCalc.expint(i, tmp);
  4735.                     EXP_INT_TABLE_A[i + EXP_INT_TABLE_MAX_INDEX] = tmp[0];
  4736.                     EXP_INT_TABLE_B[i + EXP_INT_TABLE_MAX_INDEX] = tmp[1];

  4737.                     if (i != 0) {
  4738.                         // Negative integer powers
  4739.                         FastMathCalc.splitReciprocal(tmp, recip);
  4740.                         EXP_INT_TABLE_A[EXP_INT_TABLE_MAX_INDEX - i] = recip[0];
  4741.                         EXP_INT_TABLE_B[EXP_INT_TABLE_MAX_INDEX - i] = recip[1];
  4742.                     }
  4743.                 }
  4744.             } else {
  4745.                 EXP_INT_TABLE_A = FastMathLiteralArrays.loadExpIntA();
  4746.                 EXP_INT_TABLE_B = FastMathLiteralArrays.loadExpIntB();
  4747.             }
  4748.         }
  4749.     }

  4750.     /** Enclose large data table in nested static class so it's only loaded on first access. */
  4751.     private static class ExpFracTable {
  4752.         /** Exponential over the range of 0 - 1 in increments of 2^-10
  4753.          * exp(x/1024) =  expFracTableA[x] + expFracTableB[x].
  4754.          * 1024 = 2^10
  4755.          */
  4756.         private static final double[] EXP_FRAC_TABLE_A;
  4757.         /** Exponential over the range of 0 - 1 in increments of 2^-10
  4758.          * exp(x/1024) =  expFracTableA[x] + expFracTableB[x].
  4759.          */
  4760.         private static final double[] EXP_FRAC_TABLE_B;

  4761.         static {
  4762.             if (RECOMPUTE_TABLES_AT_RUNTIME) {
  4763.                 EXP_FRAC_TABLE_A = new double[EXP_FRAC_TABLE_LEN];
  4764.                 EXP_FRAC_TABLE_B = new double[EXP_FRAC_TABLE_LEN];

  4765.                 final double[] tmp = new double[2];

  4766.                 // Populate expFracTable
  4767.                 final double factor = 1d / (EXP_FRAC_TABLE_LEN - 1);
  4768.                 for (int i = 0; i < EXP_FRAC_TABLE_A.length; i++) {
  4769.                     FastMathCalc.slowexp(i * factor, tmp);
  4770.                     EXP_FRAC_TABLE_A[i] = tmp[0];
  4771.                     EXP_FRAC_TABLE_B[i] = tmp[1];
  4772.                 }
  4773.             } else {
  4774.                 EXP_FRAC_TABLE_A = FastMathLiteralArrays.loadExpFracA();
  4775.                 EXP_FRAC_TABLE_B = FastMathLiteralArrays.loadExpFracB();
  4776.             }
  4777.         }
  4778.     }

  4779.     /** Enclose large data table in nested static class so it's only loaded on first access. */
  4780.     private static class lnMant {
  4781.         /** Extended precision logarithm table over the range 1 - 2 in increments of 2^-10. */
  4782.         private static final double[][] LN_MANT;

  4783.         static {
  4784.             if (RECOMPUTE_TABLES_AT_RUNTIME) {
  4785.                 LN_MANT = new double[LN_MANT_LEN][];

  4786.                 // Populate lnMant table
  4787.                 for (int i = 0; i < LN_MANT.length; i++) {
  4788.                     final double d = Double.longBitsToDouble( (((long) i) << 42) | 0x3ff0000000000000L );
  4789.                     LN_MANT[i] = FastMathCalc.slowLog(d);
  4790.                 }
  4791.             } else {
  4792.                 LN_MANT = FastMathLiteralArrays.loadLnMant();
  4793.             }
  4794.         }
  4795.     }

  4796.     /** Enclose the Cody/Waite reduction (used in "sin", "cos" and "tan"). */
  4797.     private static class CodyWaite {
  4798.         /** k */
  4799.         private final int finalK;
  4800.         /** remA */
  4801.         private final double finalRemA;
  4802.         /** remB */
  4803.         private final double finalRemB;

  4804.         /**
  4805.          * @param xa Argument.
  4806.          */
  4807.         CodyWaite(double xa) {
  4808.             // Estimate k.
  4809.             //k = (int)(xa / 1.5707963267948966);
  4810.             int k = (int)(xa * 0.6366197723675814);

  4811.             // Compute remainder.
  4812.             double remA;
  4813.             double remB;
  4814.             while (true) {
  4815.                 double a = -k * 1.570796251296997;
  4816.                 remA = xa + a;
  4817.                 remB = -(remA - xa - a);

  4818.                 a = -k * 7.549789948768648E-8;
  4819.                 double b = remA;
  4820.                 remA = a + b;
  4821.                 remB += -(remA - b - a);

  4822.                 a = -k * 6.123233995736766E-17;
  4823.                 b = remA;
  4824.                 remA = a + b;
  4825.                 remB += -(remA - b - a);

  4826.                 if (remA > 0) {
  4827.                     break;
  4828.                 }

  4829.                 // Remainder is negative, so decrement k and try again.
  4830.                 // This should only happen if the input is very close
  4831.                 // to an even multiple of pi/2.
  4832.                 --k;
  4833.             }

  4834.             this.finalK = k;
  4835.             this.finalRemA = remA;
  4836.             this.finalRemB = remB;
  4837.         }

  4838.         /**
  4839.          * @return k
  4840.          */
  4841.         int getK() {
  4842.             return finalK;
  4843.         }
  4844.         /**
  4845.          * @return remA
  4846.          */
  4847.         double getRemA() {
  4848.             return finalRemA;
  4849.         }
  4850.         /**
  4851.          * @return remB
  4852.          */
  4853.         double getRemB() {
  4854.             return finalRemB;
  4855.         }
  4856.     }

  4857. }