Dfp.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.dfp;

  22. import java.util.Arrays;

  23. import org.hipparchus.CalculusFieldElement;
  24. import org.hipparchus.exception.MathIllegalArgumentException;
  25. import org.hipparchus.exception.MathRuntimeException;
  26. import org.hipparchus.util.FastMath;
  27. import org.hipparchus.util.FieldSinhCosh;
  28. import org.hipparchus.util.MathUtils;

  29. /**
  30.  *  Decimal floating point library for Java
  31.  *
  32.  *  <p>Another floating point class.  This one is built using radix 10000
  33.  *  which is 10<sup>4</sup>, so its almost decimal.</p>
  34.  *
  35.  *  <p>The design goals here are:</p>
  36.  *  <ol>
  37.  *    <li>Decimal math, or close to it</li>
  38.  *    <li>Settable precision (but no mix between numbers using different settings)</li>
  39.  *    <li>Portability.  Code should be kept as portable as possible.</li>
  40.  *    <li>Performance</li>
  41.  *    <li>Accuracy  - Results should always be +/- 1 ULP for basic
  42.  *         algebraic operation</li>
  43.  *    <li>Comply with IEEE 854-1987 as much as possible.
  44.  *         (See IEEE 854-1987 notes below)</li>
  45.  *  </ol>
  46.  *
  47.  *  <p>Trade offs:</p>
  48.  *  <ol>
  49.  *    <li>Memory foot print.  I'm using more memory than necessary to
  50.  *         represent numbers to get better performance.</li>
  51.  *    <li>Digits are bigger, so rounding is a greater loss.  So, if you
  52.  *         really need 12 decimal digits, better use 4 base 10000 digits
  53.  *         there can be one partially filled.</li>
  54.  *  </ol>
  55.  *
  56.  *  <p>Numbers are represented  in the following form:
  57.  *  \[
  58.  *  n  =  \mathrm{sign} \times \mathrm{mant} \times \mathrm{radix}^\mathrm{exp}
  59.  *  \]
  60.  *  where sign is &plusmn;1, mantissa represents a fractional number between
  61.  *  zero and one.  mant[0] is the least significant digit.
  62.  *  exp is in the range of -32767 to 32768</p>
  63.  *
  64.  *  <p>IEEE 854-1987  Notes and differences</p>
  65.  *
  66.  *  <p>IEEE 854 requires the radix to be either 2 or 10.  The radix here is
  67.  *  10000, so that requirement is not met, but  it is possible that a
  68.  *  subclassed can be made to make it behave as a radix 10
  69.  *  number.  It is my opinion that if it looks and behaves as a radix
  70.  *  10 number then it is one and that requirement would be met.</p>
  71.  *
  72.  *  <p>The radix of 10000 was chosen because it should be faster to operate
  73.  *  on 4 decimal digits at once instead of one at a time.  Radix 10 behavior
  74.  *  can be realized by adding an additional rounding step to ensure that
  75.  *  the number of decimal digits represented is constant.</p>
  76.  *
  77.  *  <p>The IEEE standard specifically leaves out internal data encoding,
  78.  *  so it is reasonable to conclude that such a subclass of this radix
  79.  *  10000 system is merely an encoding of a radix 10 system.</p>
  80.  *
  81.  *  <p>IEEE 854 also specifies the existence of "sub-normal" numbers.  This
  82.  *  class does not contain any such entities.  The most significant radix
  83.  *  10000 digit is always non-zero.  Instead, we support "gradual underflow"
  84.  *  by raising the underflow flag for numbers less with exponent less than
  85.  *  expMin, but don't flush to zero until the exponent reaches MIN_EXP-digits.
  86.  *  Thus the smallest number we can represent would be:
  87.  *  1E(-(MIN_EXP-digits-1)*4),  eg, for digits=5, MIN_EXP=-32767, that would
  88.  *  be 1e-131092.</p>
  89.  *
  90.  *  <p>IEEE 854 defines that the implied radix point lies just to the right
  91.  *  of the most significant digit and to the left of the remaining digits.
  92.  *  This implementation puts the implied radix point to the left of all
  93.  *  digits including the most significant one.  The most significant digit
  94.  *  here is the one just to the right of the radix point.  This is a fine
  95.  *  detail and is really only a matter of definition.  Any side effects of
  96.  *  this can be rendered invisible by a subclass.</p>
  97.  * @see DfpField
  98.  */
  99. public class Dfp implements CalculusFieldElement<Dfp> {

  100.     /** The radix, or base of this system.  Set to 10000 */
  101.     public static final int RADIX = 10000;

  102.     /** The minimum exponent before underflow is signaled.  Flush to zero
  103.      *  occurs at minExp-DIGITS */
  104.     public static final int MIN_EXP = -32767;

  105.     /** The maximum exponent before overflow is signaled and results flushed
  106.      *  to infinity */
  107.     public static final int MAX_EXP =  32768;

  108.     /** The amount under/overflows are scaled by before going to trap handler */
  109.     public static final int ERR_SCALE = 32760;

  110.     /** Indicator value for normal finite numbers. */
  111.     public static final byte FINITE = 0;

  112.     /** Indicator value for Infinity. */
  113.     public static final byte INFINITE = 1;

  114.     /** Indicator value for signaling NaN. */
  115.     public static final byte SNAN = 2;

  116.     /** Indicator value for quiet NaN. */
  117.     public static final byte QNAN = 3;

  118.     /** String for NaN representation. */
  119.     private static final String NAN_STRING = "NaN";

  120.     /** String for positive infinity representation. */
  121.     private static final String POS_INFINITY_STRING = "Infinity";

  122.     /** String for negative infinity representation. */
  123.     private static final String NEG_INFINITY_STRING = "-Infinity";

  124.     /** Name for traps triggered by addition. */
  125.     private static final String ADD_TRAP = "add";

  126.     /** Name for traps triggered by multiplication. */
  127.     private static final String MULTIPLY_TRAP = "multiply";

  128.     /** Name for traps triggered by division. */
  129.     private static final String DIVIDE_TRAP = "divide";

  130.     /** Name for traps triggered by square root. */
  131.     private static final String SQRT_TRAP = "sqrt";

  132.     /** Name for traps triggered by alignment. */
  133.     private static final String ALIGN_TRAP = "align";

  134.     /** Name for traps triggered by truncation. */
  135.     private static final String TRUNC_TRAP = "trunc";

  136.     /** Name for traps triggered by nextAfter. */
  137.     private static final String NEXT_AFTER_TRAP = "nextAfter";

  138.     /** Name for traps triggered by lessThan. */
  139.     private static final String LESS_THAN_TRAP = "lessThan";

  140.     /** Name for traps triggered by greaterThan. */
  141.     private static final String GREATER_THAN_TRAP = "greaterThan";

  142.     /** Name for traps triggered by newInstance. */
  143.     private static final String NEW_INSTANCE_TRAP = "newInstance";

  144.     /** Multiplication factor for number of digits used to compute linear combinations. */
  145.     private static final int LINEAR_COMBINATION_DIGITS_FACTOR = 2;

  146.     /** Mantissa. */
  147.     protected int[] mant;

  148.     /** Sign bit: 1 for positive, -1 for negative. */
  149.     protected byte sign;

  150.     /** Exponent. */
  151.     protected int exp;

  152.     /** Indicator for non-finite / non-number values. */
  153.     protected byte nans;

  154.     /** Factory building similar Dfp's. */
  155.     private final DfpField field;

  156.     /** Makes an instance with a value of zero.
  157.      * @param field field to which this instance belongs
  158.      */
  159.     protected Dfp(final DfpField field) {
  160.         mant = new int[field.getRadixDigits()];
  161.         sign = 1;
  162.         exp = 0;
  163.         nans = FINITE;
  164.         this.field = field;
  165.     }

  166.     /** Create an instance from a byte value.
  167.      * @param field field to which this instance belongs
  168.      * @param x value to convert to an instance
  169.      */
  170.     protected Dfp(final DfpField field, byte x) {
  171.         this(field, (long) x);
  172.     }

  173.     /** Create an instance from an int value.
  174.      * @param field field to which this instance belongs
  175.      * @param x value to convert to an instance
  176.      */
  177.     protected Dfp(final DfpField field, int x) {
  178.         this(field, (long) x);
  179.     }

  180.     /** Create an instance from a long value.
  181.      * @param field field to which this instance belongs
  182.      * @param x value to convert to an instance
  183.      */
  184.     protected Dfp(final DfpField field, long x) {

  185.         // initialize as if 0
  186.         mant = new int[field.getRadixDigits()];
  187.         nans = FINITE;
  188.         this.field = field;

  189.         boolean isLongMin = false;
  190.         if (x == Long.MIN_VALUE) {
  191.             // special case for Long.MIN_VALUE (-9223372036854775808)
  192.             // we must shift it before taking its absolute value
  193.             isLongMin = true;
  194.             ++x;
  195.         }

  196.         // set the sign
  197.         if (x < 0) {
  198.             sign = -1;
  199.             x = -x;
  200.         } else {
  201.             sign = 1;
  202.         }

  203.         exp = 0;
  204.         while (x != 0) {
  205.             System.arraycopy(mant, mant.length - exp, mant, mant.length - 1 - exp, exp);
  206.             mant[mant.length - 1] = (int) (x % RADIX);
  207.             x /= RADIX;
  208.             exp++;
  209.         }

  210.         if (isLongMin) {
  211.             // remove the shift added for Long.MIN_VALUE
  212.             // we know in this case that fixing the last digit is sufficient
  213.             for (int i = 0; i < mant.length - 1; i++) {
  214.                 if (mant[i] != 0) {
  215.                     mant[i]++;
  216.                     break;
  217.                 }
  218.             }
  219.         }
  220.     }

  221.     /** Create an instance from a double value.
  222.      * @param field field to which this instance belongs
  223.      * @param x value to convert to an instance
  224.      */
  225.     protected Dfp(final DfpField field, double x) {

  226.         // initialize as if 0
  227.         mant = new int[field.getRadixDigits()];
  228.         this.field = field;

  229.         long bits = Double.doubleToLongBits(x);
  230.         long mantissa = bits & 0x000fffffffffffffL;
  231.         int exponent = (int) ((bits & 0x7ff0000000000000L) >> 52) - 1023;

  232.         if (exponent == -1023) {
  233.             // Zero or sub-normal
  234.             if (x == 0) {
  235.                 // make sure 0 has the right sign
  236.                 if ((bits & 0x8000000000000000L) != 0) {
  237.                     sign = -1;
  238.                 } else {
  239.                     sign = 1;
  240.                 }
  241.                 return;
  242.             }

  243.             exponent++;

  244.             // Normalize the subnormal number
  245.             while ( (mantissa & 0x0010000000000000L) == 0) {
  246.                 exponent--;
  247.                 mantissa <<= 1;
  248.             }
  249.             mantissa &= 0x000fffffffffffffL;
  250.         }

  251.         if (exponent == 1024) {
  252.             // infinity or NAN
  253.             if (x != x) {
  254.                 sign = (byte) 1;
  255.                 nans = QNAN;
  256.             } else if (x < 0) {
  257.                 sign = (byte) -1;
  258.                 nans = INFINITE;
  259.             } else {
  260.                 sign = (byte) 1;
  261.                 nans = INFINITE;
  262.             }
  263.             return;
  264.         }

  265.         Dfp xdfp = new Dfp(field, mantissa);
  266.         xdfp = xdfp.divide(new Dfp(field, 4503599627370496L)).add(field.getOne());  // Divide by 2^52, then add one
  267.         xdfp = xdfp.multiply(DfpMath.pow(field.getTwo(), exponent));

  268.         if ((bits & 0x8000000000000000L) != 0) {
  269.             xdfp = xdfp.negate();
  270.         }

  271.         System.arraycopy(xdfp.mant, 0, mant, 0, mant.length);
  272.         sign = xdfp.sign;
  273.         exp  = xdfp.exp;
  274.         nans = xdfp.nans;

  275.     }

  276.     /** Copy constructor.
  277.      * @param d instance to copy
  278.      */
  279.     public Dfp(final Dfp d) {
  280.         mant  = d.mant.clone();
  281.         sign  = d.sign;
  282.         exp   = d.exp;
  283.         nans  = d.nans;
  284.         field = d.field;
  285.     }

  286.     /** Create an instance from a String representation.
  287.      * @param field field to which this instance belongs
  288.      * @param s string representation of the instance
  289.      */
  290.     protected Dfp(final DfpField field, final String s) {

  291.         // initialize as if 0
  292.         mant = new int[field.getRadixDigits()];
  293.         sign = 1;
  294.         nans = FINITE;
  295.         this.field = field;

  296.         boolean decimalFound = false;
  297.         final int rsize = 4;   // size of radix in decimal digits
  298.         final int offset = 4;  // Starting offset into Striped
  299.         final char[] striped = new char[getRadixDigits() * rsize + offset * 2];

  300.         // Check some special cases
  301.         if (POS_INFINITY_STRING.equals(s)) {
  302.             sign = (byte) 1;
  303.             nans = INFINITE;
  304.             return;
  305.         }

  306.         if (NEG_INFINITY_STRING.equals(s)) {
  307.             sign = (byte) -1;
  308.             nans = INFINITE;
  309.             return;
  310.         }

  311.         if (NAN_STRING.equals(s)) {
  312.             sign = (byte) 1;
  313.             nans = QNAN;
  314.             return;
  315.         }

  316.         // Check for scientific notation
  317.         int p = s.indexOf('e');
  318.         if (p == -1) { // try upper case?
  319.             p = s.indexOf('E');
  320.         }

  321.         final String fpdecimal;
  322.         int sciexp = 0;
  323.         if (p != -1) {
  324.             // scientific notation
  325.             fpdecimal = s.substring(0, p);
  326.             String fpexp = s.substring(p+1);
  327.             boolean negative = false;

  328.             for (int i=0; i<fpexp.length(); i++)
  329.             {
  330.                 if (fpexp.charAt(i) == '-')
  331.                 {
  332.                     negative = true;
  333.                     continue;
  334.                 }
  335.                 if (fpexp.charAt(i) >= '0' && fpexp.charAt(i) <= '9') {
  336.                     sciexp = sciexp * 10 + fpexp.charAt(i) - '0';
  337.                 }
  338.             }

  339.             if (negative) {
  340.                 sciexp = -sciexp;
  341.             }
  342.         } else {
  343.             // normal case
  344.             fpdecimal = s;
  345.         }

  346.         // If there is a minus sign in the number then it is negative
  347.         if (fpdecimal.indexOf('-') !=  -1) {
  348.             sign = -1;
  349.         }

  350.         // First off, find all of the leading zeros, trailing zeros, and significant digits
  351.         p = 0;

  352.         // Move p to first significant digit
  353.         int decimalPos = 0;
  354.         for (;;) {
  355.             if (fpdecimal.charAt(p) >= '1' && fpdecimal.charAt(p) <= '9') {
  356.                 break;
  357.             }

  358.             if (decimalFound && fpdecimal.charAt(p) == '0') {
  359.                 decimalPos--;
  360.             }

  361.             if (fpdecimal.charAt(p) == '.') {
  362.                 decimalFound = true;
  363.             }

  364.             p++;

  365.             if (p == fpdecimal.length()) {
  366.                 break;
  367.             }
  368.         }

  369.         // Copy the string onto Stripped
  370.         int q = offset;
  371.         striped[0] = '0';
  372.         striped[1] = '0';
  373.         striped[2] = '0';
  374.         striped[3] = '0';
  375.         int significantDigits=0;
  376.         for(;;) {
  377.             if (p == (fpdecimal.length())) {
  378.                 break;
  379.             }

  380.             // Don't want to run pass the end of the array
  381.             if (q == mant.length*rsize+offset+1) {
  382.                 break;
  383.             }

  384.             if (fpdecimal.charAt(p) == '.') {
  385.                 decimalFound = true;
  386.                 decimalPos = significantDigits;
  387.                 p++;
  388.                 continue;
  389.             }

  390.             if (fpdecimal.charAt(p) < '0' || fpdecimal.charAt(p) > '9') {
  391.                 p++;
  392.                 continue;
  393.             }

  394.             striped[q] = fpdecimal.charAt(p);
  395.             q++;
  396.             p++;
  397.             significantDigits++;
  398.         }


  399.         // If the decimal point has been found then get rid of trailing zeros.
  400.         if (decimalFound && q != offset) {
  401.             for (;;) {
  402.                 q--;
  403.                 if (q == offset) {
  404.                     break;
  405.                 }
  406.                 if (striped[q] == '0') {
  407.                     significantDigits--;
  408.                 } else {
  409.                     break;
  410.                 }
  411.             }
  412.         }

  413.         // special case of numbers like "0.00000"
  414.         if (decimalFound && significantDigits == 0) {
  415.             decimalPos = 0;
  416.         }

  417.         // Implicit decimal point at end of number if not present
  418.         if (!decimalFound) {
  419.             decimalPos = q-offset;
  420.         }

  421.         // Find the number of significant trailing zeros
  422.         q = offset;  // set q to point to first sig digit
  423.         p = significantDigits-1+offset;

  424.         while (p > q) {
  425.             if (striped[p] != '0') {
  426.                 break;
  427.             }
  428.             p--;
  429.         }

  430.         // Make sure the decimal is on a mod 10000 boundary
  431.         int i = ((rsize * 100) - decimalPos - sciexp % rsize) % rsize;
  432.         q -= i;
  433.         decimalPos += i;

  434.         // Make the mantissa length right by adding zeros at the end if necessary
  435.         while ((p - q) < (mant.length * rsize)) {
  436.             for (i = 0; i < rsize; i++) {
  437.                 striped[++p] = '0';
  438.             }
  439.         }

  440.         // Ok, now we know how many trailing zeros there are,
  441.         // and where the least significant digit is
  442.         for (i = mant.length - 1; i >= 0; i--) {
  443.             mant[i] = (striped[q]   - '0') * 1000 +
  444.                       (striped[q+1] - '0') * 100  +
  445.                       (striped[q+2] - '0') * 10   +
  446.                       (striped[q+3] - '0');
  447.             q += 4;
  448.         }

  449.         exp = (decimalPos+sciexp) / rsize;

  450.         if (q < striped.length) {
  451.             // Is there possible another digit?
  452.             round((striped[q] - '0')*1000);
  453.         }

  454.     }

  455.     /** Creates an instance with a non-finite value.
  456.      * @param field field to which this instance belongs
  457.      * @param sign sign of the Dfp to create
  458.      * @param nans code of the value, must be one of {@link #INFINITE},
  459.      * {@link #SNAN},  {@link #QNAN}
  460.      */
  461.     protected Dfp(final DfpField field, final byte sign, final byte nans) {
  462.         this.field = field;
  463.         this.mant    = new int[field.getRadixDigits()];
  464.         this.sign    = sign;
  465.         this.exp     = 0;
  466.         this.nans    = nans;
  467.     }

  468.     /** Create an instance with a value of 0.
  469.      * Use this internally in preference to constructors to facilitate subclasses
  470.      * @return a new instance with a value of 0
  471.      */
  472.     public Dfp newInstance() {
  473.         return new Dfp(getField());
  474.     }

  475.     /** Create an instance from a byte value.
  476.      * @param x value to convert to an instance
  477.      * @return a new instance with value x
  478.      */
  479.     public Dfp newInstance(final byte x) {
  480.         return new Dfp(getField(), x);
  481.     }

  482.     /** Create an instance from an int value.
  483.      * @param x value to convert to an instance
  484.      * @return a new instance with value x
  485.      */
  486.     public Dfp newInstance(final int x) {
  487.         return new Dfp(getField(), x);
  488.     }

  489.     /** Create an instance from a long value.
  490.      * @param x value to convert to an instance
  491.      * @return a new instance with value x
  492.      */
  493.     public Dfp newInstance(final long x) {
  494.         return new Dfp(getField(), x);
  495.     }

  496.     /** {@inheritDoc} */
  497.     @Override
  498.     public Dfp newInstance(final double x) {
  499.         return new Dfp(getField(), x);
  500.     }

  501.     /** Create an instance by copying an existing one.
  502.      * Use this internally in preference to constructors to facilitate subclasses.
  503.      * @param d instance to copy
  504.      * @return a new instance with the same value as d
  505.      */
  506.     public Dfp newInstance(final Dfp d) {

  507.         // make sure we don't mix number with different precision
  508.         if (field.getRadixDigits() != d.field.getRadixDigits()) {
  509.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  510.             final Dfp result = newInstance(getZero());
  511.             result.nans = QNAN;
  512.             return dotrap(DfpField.FLAG_INVALID, NEW_INSTANCE_TRAP, d, result);
  513.         }

  514.         return new Dfp(d);

  515.     }

  516.     /** Create an instance from a String representation.
  517.      * Use this internally in preference to constructors to facilitate subclasses.
  518.      * @param s string representation of the instance
  519.      * @return a new instance parsed from specified string
  520.      */
  521.     public Dfp newInstance(final String s) {
  522.         return new Dfp(field, s);
  523.     }

  524.     /** Creates an instance with a non-finite value.
  525.      * @param sig sign of the Dfp to create
  526.      * @param code code of the value, must be one of {@link #INFINITE},
  527.      * {@link #SNAN},  {@link #QNAN}
  528.      * @return a new instance with a non-finite value
  529.      */
  530.     public Dfp newInstance(final byte sig, final byte code) {
  531.         return field.newDfp(sig, code);
  532.     }

  533.     /** Creates an instance by converting the instance to a different field (i.e. different accuracy).
  534.      * <p>
  535.      * If the target field as a greater number of digits, the extra least significant digits
  536.      * will be set to zero.
  537.      * </p>
  538.      * @param targetField field to convert the instance to
  539.      * @param rmode rounding mode to use if target field as less digits than the instance, can be null otherwise
  540.      * @return converted instance (or the instance itself if it already has the required number of digits)
  541.      * @see DfpField#getExtendedField(int, boolean)
  542.      * @since 1.7
  543.      */
  544.     public Dfp newInstance(final DfpField targetField, final DfpField.RoundingMode rmode) {
  545.         final int deltaLength = targetField.getRadixDigits() - field.getRadixDigits();
  546.         if (deltaLength == 0) {

  547.             // no conversion, we return the instance itself
  548.             return this;

  549.         } else {

  550.             // create an instance (initially set to 0) with the expected number of digits
  551.             Dfp result = new Dfp(targetField);
  552.             result.sign = sign;
  553.             result.exp  = exp;
  554.             result.nans = nans;
  555.             if (nans == 0) {

  556.                 if (deltaLength < 0) {

  557.                     // copy only the most significant digits, dropping the least significant ones
  558.                     // the result corresponds to pure truncation, proper rounding will follow
  559.                     System.arraycopy(mant, -deltaLength, result.mant, 0, result.mant.length);

  560.                     // check if we have dropped any non-zero digits in the low part
  561.                     // (not counting the last dropped digit which will be handled specially)
  562.                     final int last = -(deltaLength + 1);
  563.                     boolean zeroLSB = true;
  564.                     for (int i = 0; i < last; ++i) {
  565.                         zeroLSB &= mant[i] == 0;
  566.                     }

  567.                     if (!(zeroLSB && mant[last] == 0)) {
  568.                         // there are some non-zero digits that have been discarded, perform rounding

  569.                         if (shouldIncrement(rmode, zeroLSB, mant[last], result.mant[0], sign)) {
  570.                             // rounding requires incrementing the mantissa
  571.                             result.incrementMantissa();
  572.                         }

  573.                         targetField.setIEEEFlagsBits(DfpField.FLAG_INEXACT);  // signal inexact
  574.                         result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);

  575.                     }

  576.                 } else {
  577.                     // copy all digits as the new most significant ones, leaving the least significant digits to zero
  578.                     System.arraycopy(mant, 0, result.mant, deltaLength, mant.length);
  579.                 }

  580.             }

  581.             return result;

  582.         }
  583.     }

  584.     /** Check if mantissa of a truncated number must be incremented.
  585.      * <p>
  586.      * This method must be called <em>only</em> when some non-zero digits have been
  587.      * discarded (i.e. when either {@code zeroLSB} is false or {@code lastDiscarded} is non-zero),
  588.      * otherwise it would generate false positive
  589.      * </p>
  590.      * @param rmode rounding mode to use if target field as less digits than the instance, can be null otherwise
  591.      * @param zeroLSB true is least significant discarded digits (except last) are all zero
  592.      * @param lastDiscarded last discarded digit
  593.      * @param firstNonDiscarded first non-discarded digit
  594.      * @param sign of the number
  595.      * @return true if the already truncated mantissa should be incremented to achieve correct rounding
  596.      * @since 1.7
  597.      */
  598.     private static boolean shouldIncrement(final DfpField.RoundingMode rmode,
  599.                                            final boolean zeroLSB, final int lastDiscarded,
  600.                                            final int firstNonDiscarded, final int sign) {
  601.         switch (rmode) {
  602.             case ROUND_DOWN :
  603.                 return false;

  604.             case ROUND_UP :
  605.                 return true;

  606.             case ROUND_HALF_UP :
  607.                 return lastDiscarded >= 5000;

  608.             case ROUND_HALF_DOWN :
  609.                 return isAboveHalfWay(zeroLSB, lastDiscarded);

  610.             case ROUND_HALF_EVEN :
  611.                 return (isHalfWay(zeroLSB, lastDiscarded) && (firstNonDiscarded & 0x1) == 0x1) ||
  612.                        isAboveHalfWay(zeroLSB, lastDiscarded);

  613.             case ROUND_HALF_ODD :
  614.                 return (isHalfWay(zeroLSB, lastDiscarded) && (firstNonDiscarded & 0x1) == 0x0) ||
  615.                        isAboveHalfWay(zeroLSB, lastDiscarded);

  616.             case ROUND_CEIL :
  617.                 return sign > 0;

  618.             case ROUND_FLOOR :
  619.                 return sign < 0;

  620.             default :
  621.                 // this should never happen
  622.                 throw MathRuntimeException.createInternalError();
  623.         }
  624.     }

  625.     /** Increment the mantissa of the instance
  626.      * @since 1.7
  627.      */
  628.     private void incrementMantissa() {
  629.         boolean carry = true;
  630.         for (int i = 0; carry && i < mant.length; ++i) {
  631.             ++mant[i];
  632.             if (mant[i] >= RADIX) {
  633.                 mant[i] -= RADIX;
  634.             } else {
  635.                 carry = false;
  636.             }
  637.         }
  638.         if (carry) {
  639.             // we have exceeded capacity, we need to drop one digit
  640.             for (int i = 0; i < mant.length - 1; i++) {
  641.                 mant[i] = mant[i+1];
  642.             }
  643.             mant[mant.length - 1] = 1;
  644.             exp++;
  645.         }
  646.     }

  647.     /** Check if discarded digits are exactly halfway between two rounder numbers.
  648.      * @param zeroLSB true is least significant discarded digits (except last) are all zero
  649.      * @param lastDiscarded last discarded digit
  650.      * @return true if discarded digits correspond to a number exactly halfway between two rounded numbers
  651.      * @since 1.7
  652.      */
  653.     private static boolean isHalfWay(final boolean zeroLSB, final int lastDiscarded) {
  654.         return lastDiscarded == 5000 && zeroLSB;
  655.     }

  656.     /** Check if discarded digits are strictly above halfway between two rounder numbers.
  657.      * @param zeroLSB true is least significant discarded digits (except last) are all zero
  658.      * @param lastDiscarded last discarded digit
  659.      * @return true if discarded digits correspond to a number strictly above halfway between two rounded numbers
  660.      * @since 1.7
  661.      */
  662.     private static boolean isAboveHalfWay(final boolean zeroLSB, final int lastDiscarded) {
  663.         return (lastDiscarded > 5000) || (lastDiscarded == 5000 && !zeroLSB);
  664.     }

  665.     /** Get the {@link org.hipparchus.Field Field} (really a {@link DfpField}) to which the instance belongs.
  666.      * <p>
  667.      * The field is linked to the number of digits and acts as a factory
  668.      * for {@link Dfp} instances.
  669.      * </p>
  670.      * @return {@link org.hipparchus.Field Field} (really a {@link DfpField}) to which the instance belongs
  671.      */
  672.     @Override
  673.     public DfpField getField() {
  674.         return field;
  675.     }

  676.     /** Get the number of radix digits of the instance.
  677.      * @return number of radix digits
  678.      */
  679.     public int getRadixDigits() {
  680.         return field.getRadixDigits();
  681.     }

  682.     /** Get the constant 0.
  683.      * @return a Dfp with value zero
  684.      */
  685.     public Dfp getZero() {
  686.         return field.getZero();
  687.     }

  688.     /** Get the constant 1.
  689.      * @return a Dfp with value one
  690.      */
  691.     public Dfp getOne() {
  692.         return field.getOne();
  693.     }

  694.     /** Get the constant 2.
  695.      * @return a Dfp with value two
  696.      */
  697.     public Dfp getTwo() {
  698.         return field.getTwo();
  699.     }

  700.     /** Shift the mantissa left, and adjust the exponent to compensate.
  701.      */
  702.     protected void shiftLeft() {
  703.         for (int i = mant.length - 1; i > 0; i--) {
  704.             mant[i] = mant[i-1];
  705.         }
  706.         mant[0] = 0;
  707.         exp--;
  708.     }

  709.     /* Note that shiftRight() does not call round() as that round() itself
  710.      uses shiftRight() */
  711.     /** Shift the mantissa right, and adjust the exponent to compensate.
  712.      */
  713.     protected void shiftRight() {
  714.         for (int i = 0; i < mant.length - 1; i++) {
  715.             mant[i] = mant[i+1];
  716.         }
  717.         mant[mant.length - 1] = 0;
  718.         exp++;
  719.     }

  720.     /** Make our exp equal to the supplied one, this may cause rounding.
  721.      *  Also causes de-normalized numbers.  These numbers are generally
  722.      *  dangerous because most routines assume normalized numbers.
  723.      *  Align doesn't round, so it will return the last digit destroyed
  724.      *  by shifting right.
  725.      *  @param e desired exponent
  726.      *  @return last digit destroyed by shifting right
  727.      */
  728.     protected int align(int e) {
  729.         int lostdigit = 0;
  730.         boolean inexact = false;

  731.         int diff = exp - e;

  732.         int adiff = diff;
  733.         if (adiff < 0) {
  734.             adiff = -adiff;
  735.         }

  736.         if (diff == 0) {
  737.             return 0;
  738.         }

  739.         if (adiff > (mant.length + 1)) {
  740.             // Special case
  741.             Arrays.fill(mant, 0);
  742.             exp = e;

  743.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  744.             dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this);

  745.             return 0;
  746.         }

  747.         for (int i = 0; i < adiff; i++) {
  748.             if (diff < 0) {
  749.                 /* Keep track of loss -- only signal inexact after losing 2 digits.
  750.                  * the first lost digit is returned to add() and may be incorporated
  751.                  * into the result.
  752.                  */
  753.                 if (lostdigit != 0) {
  754.                     inexact = true;
  755.                 }

  756.                 lostdigit = mant[0];

  757.                 shiftRight();
  758.             } else {
  759.                 shiftLeft();
  760.             }
  761.         }

  762.         if (inexact) {
  763.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  764.             dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this);
  765.         }

  766.         return lostdigit;

  767.     }

  768.     /** Check if instance is less than x.
  769.      * @param x number to check instance against
  770.      * @return true if instance is less than x and neither are NaN, false otherwise
  771.      */
  772.     public boolean lessThan(final Dfp x) {

  773.         // make sure we don't mix number with different precision
  774.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  775.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  776.             final Dfp result = newInstance(getZero());
  777.             result.nans = QNAN;
  778.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, result);
  779.             return false;
  780.         }

  781.         /* if a nan is involved, signal invalid and return false */
  782.         if (isNaN() || x.isNaN()) {
  783.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  784.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, newInstance(getZero()));
  785.             return false;
  786.         }

  787.         return compare(this, x) < 0;
  788.     }

  789.     /** Check if instance is greater than x.
  790.      * @param x number to check instance against
  791.      * @return true if instance is greater than x and neither are NaN, false otherwise
  792.      */
  793.     public boolean greaterThan(final Dfp x) {

  794.         // make sure we don't mix number with different precision
  795.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  796.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  797.             final Dfp result = newInstance(getZero());
  798.             result.nans = QNAN;
  799.             dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, result);
  800.             return false;
  801.         }

  802.         /* if a nan is involved, signal invalid and return false */
  803.         if (isNaN() || x.isNaN()) {
  804.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  805.             dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, newInstance(getZero()));
  806.             return false;
  807.         }

  808.         return compare(this, x) > 0;
  809.     }

  810.     /** Check if instance is less than or equal to 0.
  811.      * @return true if instance is not NaN and less than or equal to 0, false otherwise
  812.      */
  813.     public boolean negativeOrNull() {

  814.         if (isNaN()) {
  815.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  816.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  817.             return false;
  818.         }

  819.         return (sign < 0) || ((mant[mant.length - 1] == 0) && !isInfinite());

  820.     }

  821.     /** Check if instance is strictly less than 0.
  822.      * @return true if instance is not NaN and less than or equal to 0, false otherwise
  823.      */
  824.     public boolean strictlyNegative() {

  825.         if (isNaN()) {
  826.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  827.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  828.             return false;
  829.         }

  830.         return (sign < 0) && ((mant[mant.length - 1] != 0) || isInfinite());

  831.     }

  832.     /** Check if instance is greater than or equal to 0.
  833.      * @return true if instance is not NaN and greater than or equal to 0, false otherwise
  834.      */
  835.     public boolean positiveOrNull() {

  836.         if (isNaN()) {
  837.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  838.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  839.             return false;
  840.         }

  841.         return (sign > 0) || ((mant[mant.length - 1] == 0) && !isInfinite());

  842.     }

  843.     /** Check if instance is strictly greater than 0.
  844.      * @return true if instance is not NaN and greater than or equal to 0, false otherwise
  845.      */
  846.     public boolean strictlyPositive() {

  847.         if (isNaN()) {
  848.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  849.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  850.             return false;
  851.         }

  852.         return (sign > 0) && ((mant[mant.length - 1] != 0) || isInfinite());

  853.     }

  854.     /** {@inheritDoc} */
  855.     @Override
  856.     public Dfp abs() {
  857.         Dfp result = newInstance(this);
  858.         result.sign = 1;
  859.         return result;
  860.     }

  861.     /** {@inheritDoc} */
  862.     @Override
  863.     public boolean isInfinite() {
  864.         return nans == INFINITE;
  865.     }

  866.     /** {@inheritDoc} */
  867.     @Override
  868.     public boolean isNaN() {
  869.         return (nans == QNAN) || (nans == SNAN);
  870.     }

  871.     /** Check if instance is equal to zero.
  872.      * @return true if instance is equal to zero
  873.      */
  874.     @Override
  875.     public boolean isZero() {

  876.         if (isNaN()) {
  877.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  878.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  879.             return false;
  880.         }

  881.         return (mant[mant.length - 1] == 0) && !isInfinite();

  882.     }

  883.     /** Check if instance is equal to x.
  884.      * @param other object to check instance against
  885.      * @return true if instance is equal to x and neither are NaN, false otherwise
  886.      */
  887.     @Override
  888.     public boolean equals(final Object other) {

  889.         if (other instanceof Dfp) {
  890.             final Dfp x = (Dfp) other;
  891.             if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) {
  892.                 return false;
  893.             }

  894.             return compare(this, x) == 0;
  895.         }

  896.         return false;

  897.     }

  898.     /**
  899.      * Gets a hashCode for the instance.
  900.      * @return a hash code value for this object
  901.      */
  902.     @Override
  903.     public int hashCode() {
  904.         return 17 + (isZero() ? 0 : (sign << 8)) + (nans << 16) + exp + Arrays.hashCode(mant);
  905.     }

  906.     /** Check if instance is not equal to x.
  907.      * @param x number to check instance against
  908.      * @return true if instance is not equal to x and neither are NaN, false otherwise
  909.      */
  910.     public boolean unequal(final Dfp x) {
  911.         if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) {
  912.             return false;
  913.         }

  914.         return greaterThan(x) || lessThan(x);
  915.     }

  916.     /** Compare two instances.
  917.      * @param a first instance in comparison
  918.      * @param b second instance in comparison
  919.      * @return -1 if a<b, 1 if a>b and 0 if a==b
  920.      *  Note this method does not properly handle NaNs or numbers with different precision.
  921.      */
  922.     private static int compare(final Dfp a, final Dfp b) {
  923.         // Ignore the sign of zero
  924.         if (a.mant[a.mant.length - 1] == 0 && b.mant[b.mant.length - 1] == 0 &&
  925.             a.nans == FINITE && b.nans == FINITE) {
  926.             return 0;
  927.         }

  928.         if (a.sign != b.sign) {
  929.             if (a.sign == -1) {
  930.                 return -1;
  931.             } else {
  932.                 return 1;
  933.             }
  934.         }

  935.         // deal with the infinities
  936.         if (a.nans == INFINITE && b.nans == FINITE) {
  937.             return a.sign;
  938.         }

  939.         if (a.nans == FINITE && b.nans == INFINITE) {
  940.             return -b.sign;
  941.         }

  942.         if (a.nans == INFINITE && b.nans == INFINITE) {
  943.             return 0;
  944.         }

  945.         // Handle special case when a or b is zero, by ignoring the exponents
  946.         if (b.mant[b.mant.length-1] != 0 && a.mant[b.mant.length-1] != 0) {
  947.             if (a.exp < b.exp) {
  948.                 return -a.sign;
  949.             }

  950.             if (a.exp > b.exp) {
  951.                 return a.sign;
  952.             }
  953.         }

  954.         // compare the mantissas
  955.         for (int i = a.mant.length - 1; i >= 0; i--) {
  956.             if (a.mant[i] > b.mant[i]) {
  957.                 return a.sign;
  958.             }

  959.             if (a.mant[i] < b.mant[i]) {
  960.                 return -a.sign;
  961.             }
  962.         }

  963.         return 0;

  964.     }

  965.     /** Round to nearest integer using the round-half-even method.
  966.      *  That is round to nearest integer unless both are equidistant.
  967.      *  In which case round to the even one.
  968.      *  @return rounded value
  969.      */
  970.     @Override
  971.     public Dfp rint() {
  972.         return trunc(DfpField.RoundingMode.ROUND_HALF_EVEN);
  973.     }

  974.     /** Round to an integer using the round floor mode.
  975.      * That is, round toward -Infinity
  976.      *  @return rounded value
  977.      */
  978.     @Override
  979.     public Dfp floor() {
  980.         return trunc(DfpField.RoundingMode.ROUND_FLOOR);
  981.     }

  982.     /** Round to an integer using the round ceil mode.
  983.      * That is, round toward +Infinity
  984.      *  @return rounded value
  985.      */
  986.     @Override
  987.     public Dfp ceil() {
  988.         return trunc(DfpField.RoundingMode.ROUND_CEIL);
  989.     }

  990.     /** Returns the IEEE remainder.
  991.      * @param d divisor
  992.      * @return this less n &times; d, where n is the integer closest to this/d
  993.      */
  994.     @Override
  995.     public Dfp remainder(final Dfp d) {

  996.         final Dfp result = this.subtract(this.divide(d).rint().multiply(d));

  997.         // IEEE 854-1987 says that if the result is zero, then it carries the sign of this
  998.         if (result.mant[mant.length-1] == 0) {
  999.             result.sign = sign;
  1000.         }

  1001.         return result;

  1002.     }

  1003.     /** Does the integer conversions with the specified rounding.
  1004.      * @param rmode rounding mode to use
  1005.      * @return truncated value
  1006.      */
  1007.     protected Dfp trunc(final DfpField.RoundingMode rmode) {
  1008.         boolean changed = false;

  1009.         if (isNaN()) {
  1010.             return newInstance(this);
  1011.         }

  1012.         if (nans == INFINITE) {
  1013.             return newInstance(this);
  1014.         }

  1015.         if (mant[mant.length-1] == 0) {
  1016.             // a is zero
  1017.             return newInstance(this);
  1018.         }

  1019.         /* If the exponent is less than zero then we can certainly
  1020.          * return -1, 0 or +1 depending on sign and rounding mode */
  1021.         if (exp < 0) {
  1022.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  1023.             final Dfp result;
  1024.             if (sign == -1 && rmode == DfpField.RoundingMode.ROUND_FLOOR) {
  1025.                 result = newInstance(-1);
  1026.             } else if (sign == +1 && rmode == DfpField.RoundingMode.ROUND_CEIL) {
  1027.                 result = newInstance(+1);
  1028.             } else {
  1029.                 // for all other combinations of sign and mode, zero is the correct rounding
  1030.                 result = newInstance(0);
  1031.             }
  1032.             return dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
  1033.         }

  1034.         /* If the exponent is greater than or equal to digits, then it
  1035.          * must already be an integer since there is no precision left
  1036.          * for any fractional part */

  1037.         if (exp >= mant.length) {
  1038.             return newInstance(this);
  1039.         }

  1040.         /* General case:  create another dfp, result, that contains the
  1041.          * a with the fractional part lopped off.  */

  1042.         Dfp result = newInstance(this);
  1043.         for (int i = 0; i < mant.length-result.exp; i++) {
  1044.             changed |= result.mant[i] != 0;
  1045.             result.mant[i] = 0;
  1046.         }

  1047.         if (changed) {
  1048.             switch (rmode) {
  1049.                 case ROUND_FLOOR:
  1050.                     if (result.sign == -1) {
  1051.                         // then we must increment the mantissa by one
  1052.                         result = result.add(newInstance(-1));
  1053.                     }
  1054.                     break;

  1055.                 case ROUND_CEIL:
  1056.                     if (result.sign == 1) {
  1057.                         // then we must increment the mantissa by one
  1058.                         result = result.add(getOne());
  1059.                     }
  1060.                     break;

  1061.                 case ROUND_HALF_EVEN:
  1062.                 default:
  1063.                     final Dfp half = newInstance("0.5");
  1064.                     Dfp a = subtract(result);  // difference between this and result
  1065.                     a.sign = 1;            // force positive (take abs)
  1066.                     if (a.greaterThan(half)) {
  1067.                         a = newInstance(getOne());
  1068.                         a.sign = sign;
  1069.                         result = result.add(a);
  1070.                     }

  1071.                     // If exactly equal to 1/2 and odd then increment
  1072.                     if (a.equals(half) && result.exp > 0 && (result.mant[mant.length-result.exp]&1) != 0) {
  1073.                         a = newInstance(getOne());
  1074.                         a.sign = sign;
  1075.                         result = result.add(a);
  1076.                     }
  1077.                     break;
  1078.             }

  1079.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);  // signal inexact
  1080.             result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
  1081.             return result;
  1082.         }

  1083.         return result;
  1084.     }

  1085.     /** Convert this to an integer.
  1086.      * If greater than 2147483647, it returns 2147483647. If less than -2147483648 it returns -2147483648.
  1087.      * @return converted number
  1088.      */
  1089.     public int intValue() {
  1090.         Dfp rounded;
  1091.         int result = 0;

  1092.         rounded = rint();

  1093.         if (rounded.greaterThan(newInstance(2147483647))) {
  1094.             return 2147483647;
  1095.         }

  1096.         if (rounded.lessThan(newInstance(-2147483648))) {
  1097.             return -2147483648;
  1098.         }

  1099.         for (int i = mant.length - 1; i >= mant.length - rounded.exp; i--) {
  1100.             result = result * RADIX + rounded.mant[i];
  1101.         }

  1102.         if (rounded.sign == -1) {
  1103.             result = -result;
  1104.         }

  1105.         return result;
  1106.     }

  1107.     /** Get the exponent of the greatest power of 10000 that is
  1108.      *  less than or equal to the absolute value of this.  I.E.  if
  1109.      *  this is 10<sup>6</sup> then log10K would return 1.
  1110.      *  @return integer base 10000 logarithm
  1111.      */
  1112.     public int log10K() {
  1113.         return exp - 1;
  1114.     }

  1115.     /** Get the specified  power of 10000.
  1116.      * @param e desired power
  1117.      * @return 10000<sup>e</sup>
  1118.      */
  1119.     public Dfp power10K(final int e) {
  1120.         Dfp d = newInstance(getOne());
  1121.         d.exp = e + 1;
  1122.         return d;
  1123.     }

  1124.     /** Get the exponent of the greatest power of 10 that is less than or equal to abs(this).
  1125.      *  @return integer base 10 logarithm
  1126.      */
  1127.     public int intLog10()  {
  1128.         if (mant[mant.length-1] > 1000) {
  1129.             return exp * 4 - 1;
  1130.         }
  1131.         if (mant[mant.length-1] > 100) {
  1132.             return exp * 4 - 2;
  1133.         }
  1134.         if (mant[mant.length-1] > 10) {
  1135.             return exp * 4 - 3;
  1136.         }
  1137.         return exp * 4 - 4;
  1138.     }

  1139.     /** Return the specified  power of 10.
  1140.      * @param e desired power
  1141.      * @return 10<sup>e</sup>
  1142.      */
  1143.     public Dfp power10(final int e) {
  1144.         Dfp d = newInstance(getOne());

  1145.         if (e >= 0) {
  1146.             d.exp = e / 4 + 1;
  1147.         } else {
  1148.             d.exp = (e + 1) / 4;
  1149.         }

  1150.         switch ((e % 4 + 4) % 4) {
  1151.             case 0:
  1152.                 break;
  1153.             case 1:
  1154.                 d = d.multiply(10);
  1155.                 break;
  1156.             case 2:
  1157.                 d = d.multiply(100);
  1158.                 break;
  1159.             default:
  1160.                 d = d.multiply(1000);
  1161.                 break;
  1162.         }

  1163.         return d;
  1164.     }

  1165.     /** Negate the mantissa of this by computing the complement.
  1166.      *  Leaves the sign bit unchanged, used internally by add.
  1167.      *  Denormalized numbers are handled properly here.
  1168.      *  @param extra ???
  1169.      *  @return ???
  1170.      */
  1171.     protected int complement(int extra) {

  1172.         extra = RADIX-extra;
  1173.         for (int i = 0; i < mant.length; i++) {
  1174.             mant[i] = RADIX-mant[i]-1;
  1175.         }

  1176.         int rh = extra / RADIX;
  1177.         extra -= rh * RADIX;
  1178.         for (int i = 0; i < mant.length; i++) {
  1179.             final int r = mant[i] + rh;
  1180.             rh = r / RADIX;
  1181.             mant[i] = r - rh * RADIX;
  1182.         }

  1183.         return extra;
  1184.     }

  1185.     /** Add x to this.
  1186.      * @param x number to add
  1187.      * @return sum of this and x
  1188.      */
  1189.     @Override
  1190.     public Dfp add(final Dfp x) {

  1191.         // make sure we don't mix number with different precision
  1192.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  1193.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1194.             final Dfp result = newInstance(getZero());
  1195.             result.nans = QNAN;
  1196.             return dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result);
  1197.         }

  1198.         /* handle special cases */
  1199.         if (nans != FINITE || x.nans != FINITE) {
  1200.             if (isNaN()) {
  1201.                 return this;
  1202.             }

  1203.             if (x.isNaN()) {
  1204.                 return x;
  1205.             }

  1206.             if (nans == INFINITE && x.nans == FINITE) {
  1207.                 return this;
  1208.             }

  1209.             if (x.nans == INFINITE && nans == FINITE) {
  1210.                 return x;
  1211.             }

  1212.             if (x.nans == INFINITE && nans == INFINITE && sign == x.sign) {
  1213.                 return x;
  1214.             }

  1215.             if (x.nans == INFINITE && nans == INFINITE && sign != x.sign) {
  1216.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1217.                 Dfp result = newInstance(getZero());
  1218.                 result.nans = QNAN;
  1219.                 result = dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result);
  1220.                 return result;
  1221.             }
  1222.         }

  1223.         /* copy this and the arg */
  1224.         Dfp a = newInstance(this);
  1225.         Dfp b = newInstance(x);

  1226.         /* initialize the result object */
  1227.         Dfp result = newInstance(getZero());

  1228.         /* Make all numbers positive, but remember their sign */
  1229.         final byte asign = a.sign;
  1230.         final byte bsign = b.sign;

  1231.         a.sign = 1;
  1232.         b.sign = 1;

  1233.         /* The result will be signed like the arg with greatest magnitude */
  1234.         byte rsign = bsign;
  1235.         if (compare(a, b) > 0) {
  1236.             rsign = asign;
  1237.         }

  1238.         /* Handle special case when a or b is zero, by setting the exponent
  1239.        of the zero number equal to the other one.  This avoids an alignment
  1240.        which would cause catastropic loss of precision */
  1241.         if (b.mant[mant.length-1] == 0) {
  1242.             b.exp = a.exp;
  1243.         }

  1244.         if (a.mant[mant.length-1] == 0) {
  1245.             a.exp = b.exp;
  1246.         }

  1247.         /* align number with the smaller exponent */
  1248.         int aextradigit = 0;
  1249.         int bextradigit = 0;
  1250.         if (a.exp < b.exp) {
  1251.             aextradigit = a.align(b.exp);
  1252.         } else {
  1253.             bextradigit = b.align(a.exp);
  1254.         }

  1255.         /* complement the smaller of the two if the signs are different */
  1256.         if (asign != bsign) {
  1257.             if (asign == rsign) {
  1258.                 bextradigit = b.complement(bextradigit);
  1259.             } else {
  1260.                 aextradigit = a.complement(aextradigit);
  1261.             }
  1262.         }

  1263.         /* add the mantissas */
  1264.         int rh = 0; /* acts as a carry */
  1265.         for (int i = 0; i < mant.length; i++) {
  1266.             final int r = a.mant[i]+b.mant[i]+rh;
  1267.             rh = r / RADIX;
  1268.             result.mant[i] = r - rh * RADIX;
  1269.         }
  1270.         result.exp = a.exp;
  1271.         result.sign = rsign;

  1272.         /* handle overflow -- note, when asign!=bsign an overflow is
  1273.          * normal and should be ignored.  */

  1274.         if (rh != 0 && (asign == bsign)) {
  1275.             final int lostdigit = result.mant[0];
  1276.             result.shiftRight();
  1277.             result.mant[mant.length-1] = rh;
  1278.             final int excp = result.round(lostdigit);
  1279.             if (excp != 0) {
  1280.                 result = dotrap(excp, ADD_TRAP, x, result);
  1281.             }
  1282.         }

  1283.         /* normalize the result */
  1284.         for (int i = 0; i < mant.length; i++) {
  1285.             if (result.mant[mant.length-1] != 0) {
  1286.                 break;
  1287.             }
  1288.             result.shiftLeft();
  1289.             if (i == 0) {
  1290.                 result.mant[0] = aextradigit+bextradigit;
  1291.                 aextradigit = 0;
  1292.                 bextradigit = 0;
  1293.             }
  1294.         }

  1295.         /* result is zero if after normalization the most sig. digit is zero */
  1296.         if (result.mant[mant.length-1] == 0) {
  1297.             result.exp = 0;

  1298.             if (asign != bsign) {
  1299.                 // Unless adding 2 negative zeros, sign is positive
  1300.                 result.sign = 1;  // Per IEEE 854-1987 Section 6.3
  1301.             }
  1302.         }

  1303.         /* Call round to test for over/under flows */
  1304.         final int excp = result.round(aextradigit + bextradigit);
  1305.         if (excp != 0) {
  1306.             result = dotrap(excp, ADD_TRAP, x, result);
  1307.         }

  1308.         return result;
  1309.     }

  1310.     /** Returns a number that is this number with the sign bit reversed.
  1311.      * @return the opposite of this
  1312.      */
  1313.     @Override
  1314.     public Dfp negate() {
  1315.         Dfp result = newInstance(this);
  1316.         result.sign = (byte) - result.sign;
  1317.         return result;
  1318.     }

  1319.     /** Subtract x from this.
  1320.      * @param x number to subtract
  1321.      * @return difference of this and a
  1322.      */
  1323.     @Override
  1324.     public Dfp subtract(final Dfp x) {
  1325.         return add(x.negate());
  1326.     }

  1327.     /** Round this given the next digit n using the current rounding mode.
  1328.      * @param n ???
  1329.      * @return the IEEE flag if an exception occurred
  1330.      */
  1331.     protected int round(int n) {
  1332.         boolean inc;
  1333.         switch (field.getRoundingMode()) {
  1334.             case ROUND_DOWN:
  1335.                 inc = false;
  1336.                 break;

  1337.             case ROUND_UP:
  1338.                 inc = n != 0;       // round up if n!=0
  1339.                 break;

  1340.             case ROUND_HALF_UP:
  1341.                 inc = n >= 5000;  // round half up
  1342.                 break;

  1343.             case ROUND_HALF_DOWN:
  1344.                 inc = n > 5000;  // round half down
  1345.                 break;

  1346.             case ROUND_HALF_EVEN:
  1347.                 inc = n > 5000 || (n == 5000 && (mant[0] & 1) == 1);  // round half-even
  1348.                 break;

  1349.             case ROUND_HALF_ODD:
  1350.                 inc = n > 5000 || (n == 5000 && (mant[0] & 1) == 0);  // round half-odd
  1351.                 break;

  1352.             case ROUND_CEIL:
  1353.                 inc = sign == 1 && n != 0;  // round ceil
  1354.                 break;

  1355.             case ROUND_FLOOR:
  1356.             default:
  1357.                 inc = sign == -1 && n != 0;  // round floor
  1358.                 break;
  1359.         }

  1360.         if (inc) {
  1361.             // increment if necessary
  1362.             int rh = 1;
  1363.             for (int i = 0; i < mant.length; i++) {
  1364.                 final int r = mant[i] + rh;
  1365.                 rh = r / RADIX;
  1366.                 mant[i] = r - rh * RADIX;
  1367.             }

  1368.             if (rh != 0) {
  1369.                 shiftRight();
  1370.                 mant[mant.length-1] = rh;
  1371.             }
  1372.         }

  1373.         // check for exceptional cases and raise signals if necessary
  1374.         if (exp < MIN_EXP) {
  1375.             // Gradual Underflow
  1376.             field.setIEEEFlagsBits(DfpField.FLAG_UNDERFLOW);
  1377.             return DfpField.FLAG_UNDERFLOW;
  1378.         }

  1379.         if (exp > MAX_EXP) {
  1380.             // Overflow
  1381.             field.setIEEEFlagsBits(DfpField.FLAG_OVERFLOW);
  1382.             return DfpField.FLAG_OVERFLOW;
  1383.         }

  1384.         if (n != 0) {
  1385.             // Inexact
  1386.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  1387.             return DfpField.FLAG_INEXACT;
  1388.         }

  1389.         return 0;

  1390.     }

  1391.     /** Multiply this by x.
  1392.      * @param x multiplicand
  1393.      * @return product of this and x
  1394.      */
  1395.     @Override
  1396.     public Dfp multiply(final Dfp x) {

  1397.         // make sure we don't mix number with different precision
  1398.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  1399.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1400.             final Dfp result = newInstance(getZero());
  1401.             result.nans = QNAN;
  1402.             return dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result);
  1403.         }

  1404.         Dfp result = newInstance(getZero());

  1405.         /* handle special cases */
  1406.         if (nans != FINITE || x.nans != FINITE) {
  1407.             if (isNaN()) {
  1408.                 return this;
  1409.             }

  1410.             if (x.isNaN()) {
  1411.                 return x;
  1412.             }

  1413.             if (nans == INFINITE && x.nans == FINITE && x.mant[mant.length-1] != 0) {
  1414.                 result = newInstance(this);
  1415.                 result.sign = (byte) (sign * x.sign);
  1416.                 return result;
  1417.             }

  1418.             if (x.nans == INFINITE && nans == FINITE && mant[mant.length-1] != 0) {
  1419.                 result = newInstance(x);
  1420.                 result.sign = (byte) (sign * x.sign);
  1421.                 return result;
  1422.             }

  1423.             if (x.nans == INFINITE && nans == INFINITE) {
  1424.                 result = newInstance(this);
  1425.                 result.sign = (byte) (sign * x.sign);
  1426.                 return result;
  1427.             }

  1428.             if ( (x.nans == INFINITE && nans == FINITE && mant[mant.length-1] == 0) ||
  1429.                     (nans == INFINITE && x.nans == FINITE && x.mant[mant.length-1] == 0) ) {
  1430.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1431.                 result = newInstance(getZero());
  1432.                 result.nans = QNAN;
  1433.                 result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result);
  1434.                 return result;
  1435.             }
  1436.         }

  1437.         int[] product = new int[mant.length*2];  // Big enough to hold even the largest result

  1438.         for (int i = 0; i < mant.length; i++) {
  1439.             int rh = 0;  // acts as a carry
  1440.             for (int j=0; j<mant.length; j++) {
  1441.                 int r = mant[i] * x.mant[j];    // multiply the 2 digits
  1442.                 r += product[i+j] + rh;  // add to the product digit with carry in

  1443.                 rh = r / RADIX;
  1444.                 product[i+j] = r - rh * RADIX;
  1445.             }
  1446.             product[i+mant.length] = rh;
  1447.         }

  1448.         // Find the most sig digit
  1449.         int md = mant.length * 2 - 1;  // default, in case result is zero
  1450.         for (int i = mant.length * 2 - 1; i >= 0; i--) {
  1451.             if (product[i] != 0) {
  1452.                 md = i;
  1453.                 break;
  1454.             }
  1455.         }

  1456.         // Copy the digits into the result
  1457.         for (int i = 0; i < mant.length; i++) {
  1458.             result.mant[mant.length - i - 1] = product[md - i];
  1459.         }

  1460.         // Fixup the exponent.
  1461.         result.exp = exp + x.exp + md - 2 * mant.length + 1;
  1462.         result.sign = (byte)((sign == x.sign)?1:-1);

  1463.         if (result.mant[mant.length-1] == 0) {
  1464.             // if result is zero, set exp to zero
  1465.             result.exp = 0;
  1466.         }

  1467.         final int excp;
  1468.         if (md > (mant.length-1)) {
  1469.             excp = result.round(product[md-mant.length]);
  1470.         } else {
  1471.             excp = result.round(0); // has no effect except to check status
  1472.         }

  1473.         if (excp != 0) {
  1474.             result = dotrap(excp, MULTIPLY_TRAP, x, result);
  1475.         }

  1476.         return result;

  1477.     }

  1478.     /** Multiply this by a single digit x.
  1479.      * @param x multiplicand
  1480.      * @return product of this and x
  1481.      */
  1482.     @Override
  1483.     public Dfp multiply(final int x) {
  1484.         if (x >= 0 && x < RADIX) {
  1485.             return multiplyFast(x);
  1486.         } else {
  1487.             return multiply(newInstance(x));
  1488.         }
  1489.     }

  1490.     /** Multiply this by a single digit 0&lt;=x&lt;radix.
  1491.      * There are speed advantages in this special case.
  1492.      * @param x multiplicand
  1493.      * @return product of this and x
  1494.      */
  1495.     private Dfp multiplyFast(final int x) {
  1496.         Dfp result = newInstance(this);

  1497.         /* handle special cases */
  1498.         if (nans != FINITE) {
  1499.             if (isNaN()) {
  1500.                 return this;
  1501.             }

  1502.             if (nans == INFINITE && x != 0) {
  1503.                 result = newInstance(this);
  1504.                 return result;
  1505.             }

  1506.             if (nans == INFINITE && x == 0) {
  1507.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1508.                 result = newInstance(getZero());
  1509.                 result.nans = QNAN;
  1510.                 result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, newInstance(getZero()), result);
  1511.                 return result;
  1512.             }
  1513.         }

  1514.         /* range check x */
  1515.         if (x < 0 || x >= RADIX) {
  1516.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1517.             result = newInstance(getZero());
  1518.             result.nans = QNAN;
  1519.             result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, result, result);
  1520.             return result;
  1521.         }

  1522.         int rh = 0;
  1523.         for (int i = 0; i < mant.length; i++) {
  1524.             final int r = mant[i] * x + rh;
  1525.             rh = r / RADIX;
  1526.             result.mant[i] = r - rh * RADIX;
  1527.         }

  1528.         int lostdigit = 0;
  1529.         if (rh != 0) {
  1530.             lostdigit = result.mant[0];
  1531.             result.shiftRight();
  1532.             result.mant[mant.length-1] = rh;
  1533.         }

  1534.         if (result.mant[mant.length-1] == 0) { // if result is zero, set exp to zero
  1535.             result.exp = 0;
  1536.         }

  1537.         final int excp = result.round(lostdigit);
  1538.         if (excp != 0) {
  1539.             result = dotrap(excp, MULTIPLY_TRAP, result, result);
  1540.         }

  1541.         return result;
  1542.     }

  1543.     /** {@inheritDoc} */
  1544.     @Override
  1545.     public Dfp square() {
  1546.         return multiply(this);
  1547.     }

  1548.     /** Divide this by divisor.
  1549.      * @param divisor divisor
  1550.      * @return quotient of this by divisor
  1551.      */
  1552.     @Override
  1553.     public Dfp divide(Dfp divisor) {
  1554.         int[] dividend; // current status of the dividend
  1555.         int[] quotient; // quotient
  1556.         int[] remainder;// remainder
  1557.         int qd;         // current quotient digit we're working with
  1558.         int nsqd;       // number of significant quotient digits we have
  1559.         int trial=0;    // trial quotient digit
  1560.         int minadj;     // minimum adjustment
  1561.         boolean trialgood; // Flag to indicate a good trail digit
  1562.         int md;         // most sig digit in result
  1563.         int excp;       // exceptions

  1564.         // make sure we don't mix number with different precision
  1565.         if (field.getRadixDigits() != divisor.field.getRadixDigits()) {
  1566.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1567.             final Dfp result = newInstance(getZero());
  1568.             result.nans = QNAN;
  1569.             return dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result);
  1570.         }

  1571.         Dfp result = newInstance(getZero());

  1572.         /* handle special cases */
  1573.         if (nans != FINITE || divisor.nans != FINITE) {
  1574.             if (isNaN()) {
  1575.                 return this;
  1576.             }

  1577.             if (divisor.isNaN()) {
  1578.                 return divisor;
  1579.             }

  1580.             if (nans == INFINITE && divisor.nans == FINITE) {
  1581.                 result = newInstance(this);
  1582.                 result.sign = (byte) (sign * divisor.sign);
  1583.                 return result;
  1584.             }

  1585.             if (divisor.nans == INFINITE && nans == FINITE) {
  1586.                 result = newInstance(getZero());
  1587.                 result.sign = (byte) (sign * divisor.sign);
  1588.                 return result;
  1589.             }

  1590.             if (divisor.nans == INFINITE && nans == INFINITE) {
  1591.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1592.                 result = newInstance(getZero());
  1593.                 result.nans = QNAN;
  1594.                 result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result);
  1595.                 return result;
  1596.             }
  1597.         }

  1598.         /* Test for divide by zero */
  1599.         if (divisor.mant[mant.length-1] == 0) {
  1600.             field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO);
  1601.             result = newInstance(getZero());
  1602.             result.sign = (byte) (sign * divisor.sign);
  1603.             result.nans = INFINITE;
  1604.             result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, divisor, result);
  1605.             return result;
  1606.         }

  1607.         dividend = new int[mant.length+1];  // one extra digit needed
  1608.         quotient = new int[mant.length+2];  // two extra digits needed 1 for overflow, 1 for rounding
  1609.         remainder = new int[mant.length+1]; // one extra digit needed

  1610.         /* Initialize our most significant digits to zero */

  1611.         dividend[mant.length] = 0;
  1612.         quotient[mant.length] = 0;
  1613.         quotient[mant.length+1] = 0;
  1614.         remainder[mant.length] = 0;

  1615.         /* copy our mantissa into the dividend, initialize the
  1616.        quotient while we are at it */

  1617.         for (int i = 0; i < mant.length; i++) {
  1618.             dividend[i] = mant[i];
  1619.             quotient[i] = 0;
  1620.             remainder[i] = 0;
  1621.         }

  1622.         /* outer loop.  Once per quotient digit */
  1623.         nsqd = 0;
  1624.         for (qd = mant.length+1; qd >= 0; qd--) {
  1625.             /* Determine outer limits of our quotient digit */

  1626.             // r =  most sig 2 digits of dividend
  1627.             final int divMsb = dividend[mant.length]*RADIX+dividend[mant.length-1];
  1628.             int min = divMsb       / (divisor.mant[mant.length-1]+1);
  1629.             int max = (divMsb + 1) / divisor.mant[mant.length-1];

  1630.             trialgood = false;
  1631.             while (!trialgood) {
  1632.                 // try the mean
  1633.                 trial = (min+max)/2;

  1634.                 /* Multiply by divisor and store as remainder */
  1635.                 int rh = 0;
  1636.                 for (int i = 0; i < mant.length + 1; i++) {
  1637.                     int dm = (i<mant.length)?divisor.mant[i]:0;
  1638.                     final int r = (dm * trial) + rh;
  1639.                     rh = r / RADIX;
  1640.                     remainder[i] = r - rh * RADIX;
  1641.                 }

  1642.                 /* subtract the remainder from the dividend */
  1643.                 rh = 1;  // carry in to aid the subtraction
  1644.                 for (int i = 0; i < mant.length + 1; i++) {
  1645.                     final int r = ((RADIX-1) - remainder[i]) + dividend[i] + rh;
  1646.                     rh = r / RADIX;
  1647.                     remainder[i] = r - rh * RADIX;
  1648.                 }

  1649.                 /* Lets analyze what we have here */
  1650.                 if (rh == 0) {
  1651.                     // trial is too big -- negative remainder
  1652.                     max = trial-1;
  1653.                     continue;
  1654.                 }

  1655.                 /* find out how far off the remainder is telling us we are */
  1656.                 minadj = (remainder[mant.length] * RADIX)+remainder[mant.length-1];
  1657.                 minadj /= divisor.mant[mant.length-1] + 1;

  1658.                 if (minadj >= 2) {
  1659.                     min = trial+minadj;  // update the minimum
  1660.                     continue;
  1661.                 }

  1662.                 /* May have a good one here, check more thoroughly.  Basically
  1663.            its a good one if it is less than the divisor */
  1664.                 trialgood = false;  // assume false
  1665.                 for (int i = mant.length - 1; i >= 0; i--) {
  1666.                     if (divisor.mant[i] > remainder[i]) {
  1667.                         trialgood = true;
  1668.                     }
  1669.                     if (divisor.mant[i] < remainder[i]) {
  1670.                         break;
  1671.                     }
  1672.                 }

  1673.                 if (remainder[mant.length] != 0) {
  1674.                     trialgood = false;
  1675.                 }

  1676.                 if (!trialgood) {
  1677.                     min = trial+1;
  1678.                 }
  1679.             }

  1680.             /* Great we have a digit! */
  1681.             quotient[qd] = trial;
  1682.             if (trial != 0 || nsqd != 0) {
  1683.                 nsqd++;
  1684.             }

  1685.             if (field.getRoundingMode() == DfpField.RoundingMode.ROUND_DOWN && nsqd == mant.length) {
  1686.                 // We have enough for this mode
  1687.                 break;
  1688.             }

  1689.             if (nsqd > mant.length) {
  1690.                 // We have enough digits
  1691.                 break;
  1692.             }

  1693.             /* move the remainder into the dividend while left shifting */
  1694.             dividend[0] = 0;
  1695.             System.arraycopy(remainder, 0, dividend, 1, mant.length);
  1696.         }

  1697.         /* Find the most sig digit */
  1698.         md = mant.length;  // default
  1699.         for (int i = mant.length + 1; i >= 0; i--) {
  1700.             if (quotient[i] != 0) {
  1701.                 md = i;
  1702.                 break;
  1703.             }
  1704.         }

  1705.         /* Copy the digits into the result */
  1706.         for (int i=0; i<mant.length; i++) {
  1707.             result.mant[mant.length-i-1] = quotient[md-i];
  1708.         }

  1709.         /* Fixup the exponent. */
  1710.         result.exp = exp - divisor.exp + md - mant.length;
  1711.         result.sign = (byte) ((sign == divisor.sign) ? 1 : -1);

  1712.         if (result.mant[mant.length-1] == 0) { // if result is zero, set exp to zero
  1713.             result.exp = 0;
  1714.         }

  1715.         if (md > (mant.length-1)) {
  1716.             excp = result.round(quotient[md-mant.length]);
  1717.         } else {
  1718.             excp = result.round(0);
  1719.         }

  1720.         if (excp != 0) {
  1721.             result = dotrap(excp, DIVIDE_TRAP, divisor, result);
  1722.         }

  1723.         return result;
  1724.     }

  1725.     /** Divide by a single digit less than radix.
  1726.      *  Special case, so there are speed advantages. 0 &lt;= divisor &lt; radix
  1727.      * @param divisor divisor
  1728.      * @return quotient of this by divisor
  1729.      */
  1730.     public Dfp divide(int divisor) {

  1731.         // Handle special cases
  1732.         if (nans != FINITE) {
  1733.             if (isNaN()) {
  1734.                 return this;
  1735.             }

  1736.             if (nans == INFINITE) {
  1737.                 return newInstance(this);
  1738.             }
  1739.         }

  1740.         // Test for divide by zero
  1741.         if (divisor == 0) {
  1742.             field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO);
  1743.             Dfp result = newInstance(getZero());
  1744.             result.sign = sign;
  1745.             result.nans = INFINITE;
  1746.             result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, getZero(), result);
  1747.             return result;
  1748.         }

  1749.         // range check divisor
  1750.         if (divisor < 0 || divisor >= RADIX) {
  1751.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1752.             Dfp result = newInstance(getZero());
  1753.             result.nans = QNAN;
  1754.             result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, result, result);
  1755.             return result;
  1756.         }

  1757.         Dfp result = newInstance(this);

  1758.         int rl = 0;
  1759.         for (int i = mant.length-1; i >= 0; i--) {
  1760.             final int r = rl*RADIX + result.mant[i];
  1761.             final int rh = r / divisor;
  1762.             rl = r - rh * divisor;
  1763.             result.mant[i] = rh;
  1764.         }

  1765.         if (result.mant[mant.length-1] == 0) {
  1766.             // normalize
  1767.             result.shiftLeft();
  1768.             final int r = rl * RADIX;        // compute the next digit and put it in
  1769.             final int rh = r / divisor;
  1770.             rl = r - rh * divisor;
  1771.             result.mant[0] = rh;
  1772.         }

  1773.         final int excp = result.round(rl * RADIX / divisor);  // do the rounding
  1774.         if (excp != 0) {
  1775.             result = dotrap(excp, DIVIDE_TRAP, result, result);
  1776.         }

  1777.         return result;

  1778.     }

  1779.     /** {@inheritDoc} */
  1780.     @Override
  1781.     public Dfp reciprocal() {
  1782.         return field.getOne().divide(this);
  1783.     }

  1784.     /** Compute the square root.
  1785.      * @return square root of the instance
  1786.      */
  1787.     @Override
  1788.     public Dfp sqrt() {

  1789.         // check for unusual cases
  1790.         if (nans == FINITE && mant[mant.length-1] == 0) {
  1791.             // if zero
  1792.             return newInstance(this);
  1793.         }

  1794.         if (nans != FINITE) {
  1795.             if (nans == INFINITE && sign == 1) {
  1796.                 // if positive infinity
  1797.                 return newInstance(this);
  1798.             }

  1799.             if (nans == QNAN) {
  1800.                 return newInstance(this);
  1801.             }

  1802.             if (nans == SNAN) {
  1803.                 Dfp result;

  1804.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1805.                 result = newInstance(this);
  1806.                 result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result);
  1807.                 return result;
  1808.             }
  1809.         }

  1810.         if (sign == -1) {
  1811.             // if negative
  1812.             Dfp result;

  1813.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1814.             result = newInstance(this);
  1815.             result.nans = QNAN;
  1816.             result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result);
  1817.             return result;
  1818.         }

  1819.         Dfp x = newInstance(this);

  1820.         /* Lets make a reasonable guess as to the size of the square root */
  1821.         if (x.exp < -1 || x.exp > 1) {
  1822.             x.exp = this.exp / 2;
  1823.         }

  1824.         /* Coarsely estimate the mantissa */
  1825.         switch (x.mant[mant.length-1] / 2000) {
  1826.             case 0:
  1827.                 x.mant[mant.length-1] = x.mant[mant.length-1]/2+1;
  1828.                 break;
  1829.             case 2:
  1830.                 x.mant[mant.length-1] = 1500;
  1831.                 break;
  1832.             case 3:
  1833.                 x.mant[mant.length-1] = 2200;
  1834.                 break;
  1835.             default:
  1836.                 x.mant[mant.length-1] = 3000;
  1837.                 break;
  1838.         }

  1839.         /* Now that we have the first pass estimate, compute the rest
  1840.        by the formula dx = (y - x*x) / (2x); */

  1841.         Dfp dx;
  1842.         Dfp px  = getZero();
  1843.         Dfp ppx;
  1844.         while (x.unequal(px)) {
  1845.             dx = newInstance(x);
  1846.             dx.sign = -1;
  1847.             dx = dx.add(this.divide(x));
  1848.             dx = dx.divide(2);
  1849.             ppx = px;
  1850.             px = x;
  1851.             x = x.add(dx);

  1852.             if (x.equals(ppx)) {
  1853.                 // alternating between two values
  1854.                 break;
  1855.             }

  1856.             // if dx is zero, break.  Note testing the most sig digit
  1857.             // is a sufficient test since dx is normalized
  1858.             if (dx.mant[mant.length-1] == 0) {
  1859.                 break;
  1860.             }
  1861.         }

  1862.         return x;

  1863.     }

  1864.     /** Get a string representation of the instance.
  1865.      * @return string representation of the instance
  1866.      */
  1867.     @Override
  1868.     public String toString() {
  1869.         if (nans != FINITE) {
  1870.             // if non-finite exceptional cases
  1871.             if (nans == INFINITE) {
  1872.                 return (sign < 0) ? NEG_INFINITY_STRING : POS_INFINITY_STRING;
  1873.             } else {
  1874.                 return NAN_STRING;
  1875.             }
  1876.         }

  1877.         if (exp > mant.length || exp < -1) {
  1878.             return dfp2sci();
  1879.         }

  1880.         return dfp2string();

  1881.     }

  1882.     /** Convert an instance to a string using scientific notation.
  1883.      * @return string representation of the instance in scientific notation
  1884.      */
  1885.     protected String dfp2sci() {
  1886.         char[] rawdigits = new char[mant.length * 4];
  1887.         int p;
  1888.         int e;
  1889.         int ae;
  1890.         int shf;

  1891.         // Get all the digits
  1892.         p = 0;
  1893.         for (int i = mant.length - 1; i >= 0; i--) {
  1894.             rawdigits[p++] = (char) ((mant[i] / 1000) + '0');
  1895.             rawdigits[p++] = (char) (((mant[i] / 100) %10) + '0');
  1896.             rawdigits[p++] = (char) (((mant[i] / 10) % 10) + '0');
  1897.             rawdigits[p++] = (char) (((mant[i]) % 10) + '0');
  1898.         }

  1899.         // Find the first non-zero one
  1900.         for (p = 0; p < rawdigits.length; p++) {
  1901.             if (rawdigits[p] != '0') {
  1902.                 break;
  1903.             }
  1904.         }
  1905.         shf = p;

  1906.         // Now do the conversion
  1907.         StringBuilder builder = new StringBuilder();
  1908.         if (sign == -1) {
  1909.             builder.append('-');
  1910.         }

  1911.         if (p != rawdigits.length) {
  1912.             // there are non zero digits...
  1913.             builder.append(rawdigits[p++]).append('.');

  1914.             while (p<rawdigits.length) {
  1915.                 builder.append(rawdigits[p++]);
  1916.             }
  1917.         } else {
  1918.             builder.append("0.0e0");
  1919.             return builder.toString();
  1920.         }

  1921.         builder.append('e');

  1922.         // Find the msd of the exponent

  1923.         e = exp * 4 - shf - 1;
  1924.         ae = e;
  1925.         if (e < 0) {
  1926.             ae = -e;
  1927.         }

  1928.         // Find the largest p such that p < e
  1929.         for (p = 1000000000; p > ae; p /= 10) { // NOPMD - empty loop is normal here
  1930.             // nothing to do
  1931.         }

  1932.         if (e < 0) {
  1933.             builder.append('-');
  1934.         }

  1935.         while (p > 0) {
  1936.             builder.append((char)(ae / p + '0'));
  1937.             ae %= p;
  1938.             p /= 10;
  1939.         }

  1940.         return builder.toString();

  1941.     }

  1942.     /** Convert an instance to a string using normal notation.
  1943.      * @return string representation of the instance in normal notation
  1944.      */
  1945.     protected String dfp2string() {
  1946.         final String fourZero = "0000";
  1947.         int e = exp;
  1948.         boolean pointInserted = false;

  1949.         StringBuilder builder = new StringBuilder(23);

  1950.         if (e <= 0) {
  1951.             builder.append("0.");
  1952.             pointInserted = true;
  1953.         }

  1954.         while (e < 0) {
  1955.             builder.append(fourZero);
  1956.             e++;
  1957.         }

  1958.         for (int i = mant.length - 1; i >= 0; i--) {
  1959.             builder.
  1960.                 append((char) ((mant[i] / 1000) + '0')).
  1961.                 append((char) (((mant[i] / 100) % 10) + '0')).
  1962.                 append((char) (((mant[i] / 10) % 10) + '0')).
  1963.                 append((char) (((mant[i]) % 10) + '0'));
  1964.             --e;
  1965.             if (e == 0) {
  1966.                 builder.append('.');
  1967.                 pointInserted = true;
  1968.             }
  1969.         }

  1970.         while (e > 0) {
  1971.             builder.append(fourZero);
  1972.             e--;
  1973.         }

  1974.         if (!pointInserted) {
  1975.             // Ensure we have a radix point!
  1976.             builder.append('.');
  1977.         }

  1978.         // Suppress leading zeros
  1979.         while (builder.charAt(0) == '0') {
  1980.             builder.deleteCharAt(0);
  1981.         }
  1982.         if (builder.charAt(0) == '.') {
  1983.             builder.insert(0, '0');
  1984.         }

  1985.         // Suppress trailing zeros
  1986.         while (builder.charAt(builder.length() - 1) == '0') {
  1987.             builder.deleteCharAt(builder.length() - 1);
  1988.         }

  1989.         // Insert sign
  1990.         if (sign < 0) {
  1991.             builder.insert(0, '-');
  1992.         }

  1993.         return builder.toString();

  1994.     }

  1995.     /** Raises a trap.  This does not set the corresponding flag however.
  1996.      *  @param type the trap type
  1997.      *  @param what - name of routine trap occurred in
  1998.      *  @param oper - input operator to function
  1999.      *  @param result - the result computed prior to the trap
  2000.      *  @return The suggested return value from the trap handler
  2001.      */
  2002.     public Dfp dotrap(int type, String what, Dfp oper, Dfp result) {
  2003.         Dfp def = result;

  2004.         switch (type) {
  2005.             case DfpField.FLAG_INVALID:
  2006.                 def = newInstance(getZero());
  2007.                 def.sign = result.sign;
  2008.                 def.nans = QNAN;
  2009.                 break;

  2010.             case DfpField.FLAG_DIV_ZERO:
  2011.                 if (nans == FINITE && mant[mant.length-1] != 0) {
  2012.                     // normal case, we are finite, non-zero
  2013.                     def = newInstance(getZero());
  2014.                     def.sign = (byte)(sign*oper.sign);
  2015.                     def.nans = INFINITE;
  2016.                 }

  2017.                 if (nans == FINITE && mant[mant.length-1] == 0) {
  2018.                     //  0/0
  2019.                     def = newInstance(getZero());
  2020.                     def.nans = QNAN;
  2021.                 }

  2022.                 if (nans == INFINITE || nans == QNAN) {
  2023.                     def = newInstance(getZero());
  2024.                     def.nans = QNAN;
  2025.                 }

  2026.                 if (nans == INFINITE || nans == SNAN) {
  2027.                     def = newInstance(getZero());
  2028.                     def.nans = QNAN;
  2029.                 }
  2030.                 break;

  2031.             case DfpField.FLAG_UNDERFLOW:
  2032.                 if ( (result.exp+mant.length) < MIN_EXP) {
  2033.                     def = newInstance(getZero());
  2034.                     def.sign = result.sign;
  2035.                 } else {
  2036.                     def = newInstance(result);  // gradual underflow
  2037.                 }
  2038.                 result.exp += ERR_SCALE;
  2039.                 break;

  2040.             case DfpField.FLAG_OVERFLOW:
  2041.                 result.exp -= ERR_SCALE;
  2042.                 def = newInstance(getZero());
  2043.                 def.sign = result.sign;
  2044.                 def.nans = INFINITE;
  2045.                 break;

  2046.             default: def = result; break;
  2047.         }

  2048.         return trap(type, what, oper, def, result);

  2049.     }

  2050.     /** Trap handler.  Subclasses may override this to provide trap
  2051.      *  functionality per IEEE 854-1987.
  2052.      *
  2053.      *  @param type  The exception type - e.g. FLAG_OVERFLOW
  2054.      *  @param what  The name of the routine we were in e.g. divide()
  2055.      *  @param oper  An operand to this function if any
  2056.      *  @param def   The default return value if trap not enabled
  2057.      *  @param result    The result that is specified to be delivered per
  2058.      *                   IEEE 854, if any
  2059.      *  @return the value that should be return by the operation triggering the trap
  2060.      */
  2061.     protected Dfp trap(int type, String what, Dfp oper, Dfp def, Dfp result) {
  2062.         return def;
  2063.     }

  2064.     /** Returns the type - one of FINITE, INFINITE, SNAN, QNAN.
  2065.      * @return type of the number
  2066.      */
  2067.     public int classify() {
  2068.         return nans;
  2069.     }

  2070.     /** Creates an instance that is the same as x except that it has the sign of y.
  2071.      * abs(x) = dfp.copysign(x, dfp.one)
  2072.      * @param x number to get the value from
  2073.      * @param y number to get the sign from
  2074.      * @return a number with the value of x and the sign of y
  2075.      */
  2076.     public static Dfp copysign(final Dfp x, final Dfp y) {
  2077.         Dfp result = x.newInstance(x);
  2078.         result.sign = y.sign;
  2079.         return result;
  2080.     }

  2081.     /** Returns the next number greater than this one in the direction of x.
  2082.      * If this==x then simply returns this.
  2083.      * @param x direction where to look at
  2084.      * @return closest number next to instance in the direction of x
  2085.      */
  2086.     public Dfp nextAfter(final Dfp x) {

  2087.         // make sure we don't mix number with different precision
  2088.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  2089.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  2090.             final Dfp result = newInstance(getZero());
  2091.             result.nans = QNAN;
  2092.             return dotrap(DfpField.FLAG_INVALID, NEXT_AFTER_TRAP, x, result);
  2093.         }

  2094.         // if this is greater than x
  2095.         boolean up = false;
  2096.         if (this.lessThan(x)) {
  2097.             up = true;
  2098.         }

  2099.         if (compare(this, x) == 0) {
  2100.             return newInstance(x);
  2101.         }

  2102.         if (lessThan(getZero())) {
  2103.             up = !up;
  2104.         }

  2105.         final Dfp inc;
  2106.         Dfp result;
  2107.         if (up) {
  2108.             inc = newInstance(getOne());
  2109.             inc.exp = this.exp-mant.length+1;
  2110.             inc.sign = this.sign;

  2111.             if (this.equals(getZero())) {
  2112.                 inc.exp = MIN_EXP-mant.length;
  2113.             }

  2114.             result = add(inc);
  2115.         } else {
  2116.             inc = newInstance(getOne());
  2117.             inc.exp = this.exp;
  2118.             inc.sign = this.sign;

  2119.             if (this.equals(inc)) {
  2120.                 inc.exp = this.exp-mant.length;
  2121.             } else {
  2122.                 inc.exp = this.exp-mant.length+1;
  2123.             }

  2124.             if (this.equals(getZero())) {
  2125.                 inc.exp = MIN_EXP-mant.length;
  2126.             }

  2127.             result = this.subtract(inc);
  2128.         }

  2129.         if (result.classify() == INFINITE && this.classify() != INFINITE) {
  2130.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  2131.             result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result);
  2132.         }

  2133.         if (result.equals(getZero()) && !this.equals(getZero())) {
  2134.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  2135.             result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result);
  2136.         }

  2137.         return result;

  2138.     }

  2139.     /** Convert the instance into a double.
  2140.      * @return a double approximating the instance
  2141.      * @see #toSplitDouble()
  2142.      */
  2143.     public double toDouble() {

  2144.         if (isInfinite()) {
  2145.             if (lessThan(getZero())) {
  2146.                 return Double.NEGATIVE_INFINITY;
  2147.             } else {
  2148.                 return Double.POSITIVE_INFINITY;
  2149.             }
  2150.         }

  2151.         if (isNaN()) {
  2152.             return Double.NaN;
  2153.         }

  2154.         Dfp y = this;
  2155.         boolean negate = false;
  2156.         int cmp0 = compare(this, getZero());
  2157.         if (cmp0 == 0) {
  2158.             return sign < 0 ? -0.0 : +0.0;
  2159.         } else if (cmp0 < 0) {
  2160.             y = negate();
  2161.             negate = true;
  2162.         }

  2163.         /* Find the exponent, first estimate by integer log10, then adjust.
  2164.          Should be faster than doing a natural logarithm.  */
  2165.         int exponent = (int)(y.intLog10() * 3.32);
  2166.         if (exponent < 0) {
  2167.             exponent--;
  2168.         }

  2169.         Dfp tempDfp = DfpMath.pow(getTwo(), exponent);
  2170.         while (tempDfp.lessThan(y) || tempDfp.equals(y)) {
  2171.             tempDfp = tempDfp.multiply(2);
  2172.             exponent++;
  2173.         }
  2174.         exponent--;

  2175.         /* We have the exponent, now work on the mantissa */

  2176.         y = y.divide(DfpMath.pow(getTwo(), exponent));
  2177.         if (exponent > -1023) {
  2178.             y = y.subtract(getOne());
  2179.         }

  2180.         if (exponent < -1074) {
  2181.             return 0;
  2182.         }

  2183.         if (exponent > 1023) {
  2184.             return negate ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
  2185.         }


  2186.         y = y.multiply(newInstance(4503599627370496L)).rint();
  2187.         String str = y.toString();
  2188.         str = str.substring(0, str.length()-1);
  2189.         long mantissa = Long.parseLong(str);

  2190.         if (mantissa == 4503599627370496L) {
  2191.             // Handle special case where we round up to next power of two
  2192.             mantissa = 0;
  2193.             exponent++;
  2194.         }

  2195.         /* Its going to be subnormal, so make adjustments */
  2196.         if (exponent <= -1023) {
  2197.             exponent--;
  2198.         }

  2199.         while (exponent < -1023) {
  2200.             exponent++;
  2201.             mantissa >>>= 1;
  2202.         }

  2203.         long bits = mantissa | ((exponent + 1023L) << 52);
  2204.         double x = Double.longBitsToDouble(bits);

  2205.         if (negate) {
  2206.             x = -x;
  2207.         }

  2208.         return x;

  2209.     }

  2210.     /** Convert the instance into a split double.
  2211.      * @return an array of two doubles which sum represent the instance
  2212.      * @see #toDouble()
  2213.      */
  2214.     public double[] toSplitDouble() {
  2215.         double[] split = new double[2];
  2216.         long mask = 0xffffffffc0000000L;

  2217.         split[0] = Double.longBitsToDouble(Double.doubleToLongBits(toDouble()) & mask);
  2218.         split[1] = subtract(newInstance(split[0])).toDouble();

  2219.         return split;
  2220.     }

  2221.     /** {@inheritDoc}
  2222.      */
  2223.     @Override
  2224.     public double getReal() {
  2225.         return toDouble();
  2226.     }

  2227.     /** {@inheritDoc} */
  2228.     @Override
  2229.     public Dfp getAddendum() {
  2230.         return isFinite() ? subtract(getReal()) : getZero();
  2231.     }

  2232.     /** {@inheritDoc}
  2233.      */
  2234.     @Override
  2235.     public Dfp remainder(final double a) {
  2236.         return remainder(newInstance(a));
  2237.     }

  2238.     /** {@inheritDoc}
  2239.      */
  2240.     @Override
  2241.     public Dfp sign() {
  2242.         if (isNaN() || isZero()) {
  2243.             return this;
  2244.         } else {
  2245.             return newInstance(sign > 0 ? +1 : -1);
  2246.         }
  2247.     }

  2248.     /** {@inheritDoc}
  2249.      */
  2250.     @Override
  2251.     public Dfp copySign(final Dfp s) {
  2252.         if ((sign >= 0 && s.sign >= 0) || (sign < 0 && s.sign < 0)) { // Sign is currently OK
  2253.             return this;
  2254.         }
  2255.         return negate(); // flip sign
  2256.     }

  2257.     /** {@inheritDoc}
  2258.      */
  2259.     @Override
  2260.     public Dfp copySign(final double s) {
  2261.         long sb = Double.doubleToLongBits(s);
  2262.         if ((sign >= 0 && sb >= 0) || (sign < 0 && sb < 0)) { // Sign is currently OK
  2263.             return this;
  2264.         }
  2265.         return negate(); // flip sign
  2266.     }

  2267.     /** {@inheritDoc}
  2268.      */
  2269.     @Override
  2270.     public int getExponent() {

  2271.         if (nans != FINITE) {
  2272.             // 2⁴³⁵⁴¹¹ < 10000³²⁷⁶⁸ < 2⁴³⁵⁴¹²
  2273.             return 435411;
  2274.         }
  2275.         if (isZero()) {
  2276.             return -435412;
  2277.         }

  2278.         final Dfp abs = abs();

  2279.         // estimate a lower bound for binary exponent
  2280.         // 13301/1001 is a continued fraction approximation of ln(10000)/ln(2)
  2281.         int p = FastMath.max(13301 * exp / 1001 - 15, -435411);
  2282.         Dfp twoP = DfpMath.pow(getTwo(), p);
  2283.         while (compare(abs, twoP) >= 0) {
  2284.             twoP = twoP.add(twoP);
  2285.             ++p;
  2286.         }

  2287.         return p - 1;

  2288.     }

  2289.     /** {@inheritDoc}
  2290.      */
  2291.     @Override
  2292.     public Dfp scalb(final int n) {
  2293.         return multiply(DfpMath.pow(getTwo(), n));
  2294.     }

  2295.     /** {@inheritDoc}
  2296.      */
  2297.     @Override
  2298.     public Dfp ulp() {
  2299.         final Dfp result = new Dfp(field);
  2300.         result.mant[result.mant.length - 1] = 1;
  2301.         result.exp = exp - (result.mant.length - 1);
  2302.         return result;
  2303.     }

  2304.     /** {@inheritDoc}
  2305.      */
  2306.     @Override
  2307.     public Dfp hypot(final Dfp y) {

  2308.         if (isInfinite() || y.isInfinite()) {
  2309.             return field.newDfp(Double.POSITIVE_INFINITY);
  2310.         } else if (isNaN() || y.isNaN()) {
  2311.             return field.newDfp(Double.NaN);
  2312.         } else {
  2313.             // find scaling to avoid both overflow and underflow
  2314.             final int scalingExp = (exp + y.exp) / 2;

  2315.             // scale both operands
  2316.             final Dfp scaledX = new Dfp(this);
  2317.             scaledX.exp -= scalingExp;
  2318.             final Dfp scaledY = new Dfp(y);
  2319.             scaledY.exp -= scalingExp;

  2320.             // compute scaled hypothenuse
  2321.             final Dfp h = scaledX.multiply(scaledX).add(scaledY.multiply(scaledY)).sqrt();

  2322.             // scale result
  2323.             h.exp += scalingExp;

  2324.             return h;
  2325.         }

  2326.     }

  2327.     /** {@inheritDoc}
  2328.      */
  2329.     @Override
  2330.     public Dfp rootN(final int n) {
  2331.         return (sign >= 0) ?
  2332.                DfpMath.pow(this, getOne().divide(n)) :
  2333.                DfpMath.pow(negate(), getOne().divide(n)).negate();
  2334.     }

  2335.     /** {@inheritDoc}
  2336.      */
  2337.     @Override
  2338.     public Dfp pow(final double p) {
  2339.         return DfpMath.pow(this, newInstance(p));
  2340.     }

  2341.     /** {@inheritDoc}
  2342.      */
  2343.     @Override
  2344.     public Dfp pow(final int n) {
  2345.         return DfpMath.pow(this, n);
  2346.     }

  2347.     /** {@inheritDoc}
  2348.      */
  2349.     @Override
  2350.     public Dfp pow(final Dfp e) {
  2351.         return DfpMath.pow(this, e);
  2352.     }

  2353.     /** {@inheritDoc}
  2354.      */
  2355.     @Override
  2356.     public Dfp exp() {
  2357.         return DfpMath.exp(this);
  2358.     }

  2359.     /** {@inheritDoc}
  2360.      */
  2361.     @Override
  2362.     public Dfp expm1() {
  2363.         return DfpMath.exp(this).subtract(getOne());
  2364.     }

  2365.     /** {@inheritDoc}
  2366.      */
  2367.     @Override
  2368.     public Dfp log() {
  2369.         return DfpMath.log(this);
  2370.     }

  2371.     /** {@inheritDoc}
  2372.      */
  2373.     @Override
  2374.     public Dfp log1p() {
  2375.         return DfpMath.log(this.add(getOne()));
  2376.     }

  2377.     /** {@inheritDoc}
  2378.      */
  2379.     @Override
  2380.     public Dfp log10() {
  2381.         return DfpMath.log(this).divide(DfpMath.log(newInstance(10)));
  2382.     }

  2383.     /** {@inheritDoc}
  2384.      */
  2385.     @Override
  2386.     public Dfp cos() {
  2387.         return DfpMath.cos(this);
  2388.     }

  2389.     /** {@inheritDoc}
  2390.      */
  2391.     @Override
  2392.     public Dfp sin() {
  2393.         return DfpMath.sin(this);
  2394.     }

  2395.     /** {@inheritDoc}
  2396.      */
  2397.     @Override
  2398.     public Dfp tan() {
  2399.         return DfpMath.tan(this);
  2400.     }

  2401.     /** {@inheritDoc}
  2402.      */
  2403.     @Override
  2404.     public Dfp acos() {
  2405.         return DfpMath.acos(this);
  2406.     }

  2407.     /** {@inheritDoc}
  2408.      */
  2409.     @Override
  2410.     public Dfp asin() {
  2411.         return DfpMath.asin(this);
  2412.     }

  2413.     /** {@inheritDoc}
  2414.      */
  2415.     @Override
  2416.     public Dfp atan() {
  2417.         return DfpMath.atan(this);
  2418.     }

  2419.     /** {@inheritDoc}
  2420.      */
  2421.     @Override
  2422.     public Dfp atan2(final Dfp x)
  2423.         throws MathIllegalArgumentException {

  2424.         // compute r = sqrt(x^2+y^2)
  2425.         final Dfp r = x.square().add(multiply(this)).sqrt();
  2426.         if (r.isZero()) {
  2427.             // special cases handling
  2428.             if (x.sign >= 0) {
  2429.                 return this; // ±0.0
  2430.             } else {
  2431.                 return newInstance((sign <= 0) ? -FastMath.PI : FastMath.PI); // ±π
  2432.             }
  2433.         }

  2434.         if (x.sign >= 0) {

  2435.             // compute atan2(y, x) = 2 atan(y / (r + x))
  2436.             return getTwo().multiply(divide(r.add(x)).atan());

  2437.         } else {

  2438.             // compute atan2(y, x) = +/- pi - 2 atan(y / (r - x))
  2439.             final Dfp tmp = getTwo().multiply(divide(r.subtract(x)).atan());
  2440.             final Dfp pmPi = newInstance((tmp.sign <= 0) ? -FastMath.PI : FastMath.PI);
  2441.             return pmPi.subtract(tmp);

  2442.         }

  2443.     }

  2444.     /** {@inheritDoc}
  2445.      */
  2446.     @Override
  2447.     public Dfp cosh() {
  2448.         return DfpMath.exp(this).add(DfpMath.exp(negate())).multiply(0.5);
  2449.     }

  2450.     /** {@inheritDoc}
  2451.      */
  2452.     @Override
  2453.     public Dfp sinh() {
  2454.         return DfpMath.exp(this).subtract(DfpMath.exp(negate())).multiply(0.5);
  2455.     }

  2456.     /** {@inheritDoc}
  2457.      */
  2458.     @Override
  2459.     public FieldSinhCosh<Dfp> sinhCosh() {
  2460.         final Dfp p = DfpMath.exp(this);
  2461.         final Dfp m = DfpMath.exp(negate());
  2462.         return new FieldSinhCosh<>(p.subtract(m).multiply(0.5), p.add(m).multiply(0.5));
  2463.     }

  2464.     /** {@inheritDoc}
  2465.      */
  2466.     @Override
  2467.     public Dfp tanh() {
  2468.         final Dfp ePlus  = DfpMath.exp(this);
  2469.         final Dfp eMinus = DfpMath.exp(negate());
  2470.         return ePlus.subtract(eMinus).divide(ePlus.add(eMinus));
  2471.     }

  2472.     /** {@inheritDoc}
  2473.      */
  2474.     @Override
  2475.     public Dfp acosh() {
  2476.         return square().subtract(getOne()).sqrt().add(this).log();
  2477.     }

  2478.     /** {@inheritDoc}
  2479.      */
  2480.     @Override
  2481.     public Dfp asinh() {
  2482.         return square().add(getOne()).sqrt().add(this).log();
  2483.     }

  2484.     /** {@inheritDoc}
  2485.      */
  2486.     @Override
  2487.     public Dfp atanh() {
  2488.         return getOne().add(this).divide(getOne().subtract(this)).log().divide(2);
  2489.     }

  2490.     /** {@inheritDoc} */
  2491.     @Override
  2492.     public Dfp toDegrees() {
  2493.         return multiply(field.getRadToDeg());
  2494.     }

  2495.     /** {@inheritDoc} */
  2496.     @Override
  2497.     public Dfp toRadians() {
  2498.         return multiply(field.getDegToRad());
  2499.     }

  2500.     /** {@inheritDoc}
  2501.      */
  2502.     @Override
  2503.     public Dfp linearCombination(final Dfp[] a, final Dfp[] b)
  2504.         throws MathIllegalArgumentException {

  2505.         MathUtils.checkDimension(a.length, b.length);

  2506.         // compute in extended accuracy
  2507.         final DfpField extendedField = a[0].field.getExtendedField(LINEAR_COMBINATION_DIGITS_FACTOR, false);
  2508.         Dfp r = extendedField.getZero();
  2509.         for (int i = 0; i < a.length; ++i) {
  2510.             final Dfp aiExt = a[i].newInstance(extendedField, null);
  2511.             final Dfp biExt = b[i].newInstance(extendedField, null);
  2512.             r = r.add(aiExt.multiply(biExt));
  2513.         }

  2514.         // back to normal accuracy
  2515.         return r.newInstance(a[0].field, DfpField.RoundingMode.ROUND_HALF_EVEN);

  2516.     }

  2517.     /** {@inheritDoc}
  2518.      */
  2519.     @Override
  2520.     public Dfp linearCombination(final double[] a, final Dfp[] b)
  2521.         throws MathIllegalArgumentException {

  2522.         MathUtils.checkDimension(a.length, b.length);

  2523.         // compute in extended accuracy
  2524.         final DfpField extendedField = b[0].field.getExtendedField(LINEAR_COMBINATION_DIGITS_FACTOR, false);
  2525.         Dfp r = extendedField.getZero();
  2526.         for (int i = 0; i < a.length; ++i) {
  2527.             final Dfp biExt = b[i].newInstance(extendedField, null);
  2528.             r = r.add(biExt.multiply(a[i]));
  2529.         }

  2530.         // back to normal accuracy
  2531.         return r.newInstance(b[0].field, DfpField.RoundingMode.ROUND_HALF_EVEN);

  2532.     }

  2533.     /** {@inheritDoc}
  2534.      */
  2535.     @Override
  2536.     public Dfp linearCombination(final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2) {

  2537.         // switch to extended accuracy
  2538.         final DfpField extendedField = a1.field.getExtendedField(LINEAR_COMBINATION_DIGITS_FACTOR, false);
  2539.         final Dfp a1Ext = a1.newInstance(extendedField, null);
  2540.         final Dfp b1Ext = b1.newInstance(extendedField, null);
  2541.         final Dfp a2Ext = a2.newInstance(extendedField, null);
  2542.         final Dfp b2Ext = b2.newInstance(extendedField, null);

  2543.         // compute linear combination in extended accuracy
  2544.         final Dfp resultExt = a1Ext.multiply(b1Ext).
  2545.                           add(a2Ext.multiply(b2Ext));

  2546.         // back to normal accuracy
  2547.         return resultExt.newInstance(a1.field, DfpField.RoundingMode.ROUND_HALF_EVEN);

  2548.     }

  2549.     /** {@inheritDoc}
  2550.      */
  2551.     @Override
  2552.     public Dfp linearCombination(final double a1, final Dfp b1, final double a2, final Dfp b2) {

  2553.         // switch to extended accuracy
  2554.         final DfpField extendedField = b1.field.getExtendedField(LINEAR_COMBINATION_DIGITS_FACTOR, false);
  2555.         final Dfp b1Ext = b1.newInstance(extendedField, null);
  2556.         final Dfp b2Ext = b2.newInstance(extendedField, null);

  2557.         // compute linear combination in extended accuracy
  2558.         final Dfp resultExt = b1Ext.multiply(a1).
  2559.                           add(b2Ext.multiply(a2));

  2560.         // back to normal accuracy
  2561.         return resultExt.newInstance(b1.field, DfpField.RoundingMode.ROUND_HALF_EVEN);

  2562.     }

  2563.     /** {@inheritDoc}
  2564.      */
  2565.     @Override
  2566.     public Dfp linearCombination(final Dfp a1, final Dfp b1,
  2567.                                  final Dfp a2, final Dfp b2,
  2568.                                  final Dfp a3, final Dfp b3) {

  2569.         // switch to extended accuracy
  2570.         final DfpField extendedField = a1.field.getExtendedField(LINEAR_COMBINATION_DIGITS_FACTOR, false);
  2571.         final Dfp a1Ext = a1.newInstance(extendedField, null);
  2572.         final Dfp b1Ext = b1.newInstance(extendedField, null);
  2573.         final Dfp a2Ext = a2.newInstance(extendedField, null);
  2574.         final Dfp b2Ext = b2.newInstance(extendedField, null);
  2575.         final Dfp a3Ext = a3.newInstance(extendedField, null);
  2576.         final Dfp b3Ext = b3.newInstance(extendedField, null);

  2577.         // compute linear combination in extended accuracy
  2578.         final Dfp resultExt = a1Ext.multiply(b1Ext).
  2579.                           add(a2Ext.multiply(b2Ext)).
  2580.                           add(a3Ext.multiply(b3Ext));

  2581.         // back to normal accuracy
  2582.         return resultExt.newInstance(a1.field, DfpField.RoundingMode.ROUND_HALF_EVEN);

  2583.     }

  2584.     /** {@inheritDoc}
  2585.      */
  2586.     @Override
  2587.     public Dfp linearCombination(final double a1, final Dfp b1,
  2588.                                  final double a2, final Dfp b2,
  2589.                                  final double a3, final Dfp b3) {

  2590.         // switch to extended accuracy
  2591.         final DfpField extendedField = b1.field.getExtendedField(LINEAR_COMBINATION_DIGITS_FACTOR, false);
  2592.         final Dfp b1Ext = b1.newInstance(extendedField, null);
  2593.         final Dfp b2Ext = b2.newInstance(extendedField, null);
  2594.         final Dfp b3Ext = b3.newInstance(extendedField, null);

  2595.         // compute linear combination in extended accuracy
  2596.         final Dfp resultExt = b1Ext.multiply(a1).
  2597.                           add(b2Ext.multiply(a2)).
  2598.                           add(b3Ext.multiply(a3));

  2599.         // back to normal accuracy
  2600.         return resultExt.newInstance(b1.field, DfpField.RoundingMode.ROUND_HALF_EVEN);

  2601.     }

  2602.     /** {@inheritDoc}
  2603.      */
  2604.     @Override
  2605.     public Dfp linearCombination(final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2,
  2606.                                  final Dfp a3, final Dfp b3, final Dfp a4, final Dfp b4) {

  2607.         // switch to extended accuracy
  2608.         final DfpField extendedField = a1.field.getExtendedField(LINEAR_COMBINATION_DIGITS_FACTOR, false);
  2609.         final Dfp a1Ext = a1.newInstance(extendedField, null);
  2610.         final Dfp b1Ext = b1.newInstance(extendedField, null);
  2611.         final Dfp a2Ext = a2.newInstance(extendedField, null);
  2612.         final Dfp b2Ext = b2.newInstance(extendedField, null);
  2613.         final Dfp a3Ext = a3.newInstance(extendedField, null);
  2614.         final Dfp b3Ext = b3.newInstance(extendedField, null);
  2615.         final Dfp a4Ext = a4.newInstance(extendedField, null);
  2616.         final Dfp b4Ext = b4.newInstance(extendedField, null);

  2617.         // compute linear combination in extended accuracy
  2618.         final Dfp resultExt = a1Ext.multiply(b1Ext).
  2619.                           add(a2Ext.multiply(b2Ext)).
  2620.                           add(a3Ext.multiply(b3Ext)).
  2621.                           add(a4Ext.multiply(b4Ext));

  2622.         // back to normal accuracy
  2623.         return resultExt.newInstance(a1.field, DfpField.RoundingMode.ROUND_HALF_EVEN);

  2624.     }

  2625.     /** {@inheritDoc}
  2626.      */
  2627.     @Override
  2628.     public Dfp linearCombination(final double a1, final Dfp b1, final double a2, final Dfp b2,
  2629.                                  final double a3, final Dfp b3, final double a4, final Dfp b4) {

  2630.         // switch to extended accuracy
  2631.         final DfpField extendedField = b1.field.getExtendedField(LINEAR_COMBINATION_DIGITS_FACTOR, false);
  2632.         final Dfp b1Ext = b1.newInstance(extendedField, null);
  2633.         final Dfp b2Ext = b2.newInstance(extendedField, null);
  2634.         final Dfp b3Ext = b3.newInstance(extendedField, null);
  2635.         final Dfp b4Ext = b4.newInstance(extendedField, null);

  2636.         // compute linear combination in extended accuracy
  2637.         final Dfp resultExt = b1Ext.multiply(a1).
  2638.                           add(b2Ext.multiply(a2)).
  2639.                           add(b3Ext.multiply(a3)).
  2640.                           add(b4Ext.multiply(a4));

  2641.         // back to normal accuracy
  2642.         return resultExt.newInstance(b1.field, DfpField.RoundingMode.ROUND_HALF_EVEN);

  2643.     }

  2644.     /** {@inheritDoc} */
  2645.     @Override
  2646.     public Dfp getPi() {
  2647.         return field.getPi();
  2648.     }

  2649. }