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.  *      http://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. package org.apache.commons.math4.legacy.core.dfp;

  18. import java.util.Arrays;

  19. import org.apache.commons.math4.legacy.core.RealFieldElement;
  20. import org.apache.commons.math4.legacy.exception.DimensionMismatchException;

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

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

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

  98.     /** The maximum exponent before overflow is signaled and results flushed
  99.      *  to infinity. */
  100.     public static final int MAX_EXP =  32768;

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

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

  105.     /** Indicator value for Infinity. */
  106.     public static final byte INFINITE = 1;

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

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

  111.     /** String for NaN representation. */
  112.     private static final String NAN_STRING = "NaN";

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

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

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

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

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

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

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

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

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

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

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

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

  137.     /** Mantissa. */
  138.     protected int[] mant;

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

  141.     /** Exponent. */
  142.     protected int exp;

  143.     /** Indicator for non-finite / non-number values. */
  144.     protected byte nans;

  145.     /** Factory building similar Dfp's. */
  146.     private final DfpField field;

  147.     /** Makes an instance with a value of zero.
  148.      * @param field field to which this instance belongs
  149.      */
  150.     protected Dfp(final DfpField field) {
  151.         mant = new int[field.getRadixDigits()];
  152.         sign = 1;
  153.         exp = 0;
  154.         nans = FINITE;
  155.         this.field = field;
  156.     }

  157.     /** Create an instance from a byte value.
  158.      * @param field field to which this instance belongs
  159.      * @param x value to convert to an instance
  160.      */
  161.     protected Dfp(final DfpField field, byte x) {
  162.         this(field, (long) x);
  163.     }

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

  171.     /** Create an instance from a long value.
  172.      * @param field field to which this instance belongs
  173.      * @param x value to convert to an instance
  174.      */
  175.     protected Dfp(final DfpField field, long x) {

  176.         // initialize as if 0
  177.         mant = new int[field.getRadixDigits()];
  178.         nans = FINITE;
  179.         this.field = field;

  180.         boolean isLongMin = false;
  181.         if (x == Long.MIN_VALUE) {
  182.             // special case for Long.MIN_VALUE (-9223372036854775808)
  183.             // we must shift it before taking its absolute value
  184.             isLongMin = true;
  185.             ++x;
  186.         }

  187.         // set the sign
  188.         if (x < 0) {
  189.             sign = -1;
  190.             x = -x;
  191.         } else {
  192.             sign = 1;
  193.         }

  194.         exp = 0;
  195.         while (x != 0) {
  196.             System.arraycopy(mant, mant.length - exp, mant, mant.length - 1 - exp, exp);
  197.             mant[mant.length - 1] = (int) (x % RADIX);
  198.             x /= RADIX;
  199.             exp++;
  200.         }

  201.         if (isLongMin) {
  202.             // remove the shift added for Long.MIN_VALUE
  203.             // we know in this case that fixing the last digit is sufficient
  204.             for (int i = 0; i < mant.length - 1; i++) {
  205.                 if (mant[i] != 0) {
  206.                     mant[i]++;
  207.                     break;
  208.                 }
  209.             }
  210.         }
  211.     }

  212.     /** Create an instance from a double value.
  213.      * @param field field to which this instance belongs
  214.      * @param x value to convert to an instance
  215.      */
  216.     protected Dfp(final DfpField field, double x) {

  217.         // initialize as if 0
  218.         mant = new int[field.getRadixDigits()];
  219.         sign = 1;
  220.         exp = 0;
  221.         nans = FINITE;
  222.         this.field = field;

  223.         long bits = Double.doubleToLongBits(x);
  224.         long mantissa = bits & 0x000fffffffffffffL;
  225.         int exponent = (int) ((bits & 0x7ff0000000000000L) >> 52) - 1023;

  226.         if (exponent == -1023) {
  227.             // Zero or sub-normal
  228.             if (x == 0) {
  229.                 // make sure 0 has the right sign
  230.                 if ((bits & 0x8000000000000000L) != 0) {
  231.                     sign = -1;
  232.                 }
  233.                 return;
  234.             }

  235.             exponent++;

  236.             // Normalize the subnormal number
  237.             while ((mantissa & 0x0010000000000000L) == 0) {
  238.                 exponent--;
  239.                 mantissa <<= 1;
  240.             }
  241.             mantissa &= 0x000fffffffffffffL;
  242.         }

  243.         if (exponent == 1024) {
  244.             // infinity or NAN
  245.             if (Double.isNaN(x)) {
  246.                 sign = (byte) 1;
  247.                 nans = QNAN;
  248.             } else if (x < 0) {
  249.                 sign = (byte) -1;
  250.                 nans = INFINITE;
  251.             } else {
  252.                 sign = (byte) 1;
  253.                 nans = INFINITE;
  254.             }
  255.             return;
  256.         }

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

  260.         if ((bits & 0x8000000000000000L) != 0) {
  261.             xdfp = xdfp.negate();
  262.         }

  263.         System.arraycopy(xdfp.mant, 0, mant, 0, mant.length);
  264.         sign = xdfp.sign;
  265.         exp  = xdfp.exp;
  266.         nans = xdfp.nans;
  267.     }

  268.     /** Copy constructor.
  269.      * @param d instance to copy
  270.      */
  271.     public Dfp(final Dfp d) {
  272.         mant  = d.mant.clone();
  273.         sign  = d.sign;
  274.         exp   = d.exp;
  275.         nans  = d.nans;
  276.         field = d.field;
  277.     }

  278.     /** Create an instance from a String representation.
  279.      * @param field field to which this instance belongs
  280.      * @param s string representation of the instance
  281.      */
  282.     protected Dfp(final DfpField field, final String s) {

  283.         // initialize as if 0
  284.         mant = new int[field.getRadixDigits()];
  285.         sign = 1;
  286.         exp = 0;
  287.         nans = FINITE;
  288.         this.field = field;

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

  293.         // Check some special cases
  294.         if (s.equals(POS_INFINITY_STRING)) {
  295.             sign = (byte) 1;
  296.             nans = INFINITE;
  297.             return;
  298.         }

  299.         if (s.equals(NEG_INFINITY_STRING)) {
  300.             sign = (byte) -1;
  301.             nans = INFINITE;
  302.             return;
  303.         }

  304.         if (s.equals(NAN_STRING)) {
  305.             sign = (byte) 1;
  306.             nans = QNAN;
  307.             return;
  308.         }

  309.         // Check for scientific notation
  310.         int p = s.indexOf("e");
  311.         if (p == -1) { // try upper case?
  312.             p = s.indexOf("E");
  313.         }

  314.         final String fpdecimal;
  315.         int sciexp = 0;
  316.         if (p != -1) {
  317.             // scientific notation
  318.             fpdecimal = s.substring(0, p);
  319.             String fpexp = s.substring(p + 1);
  320.             boolean negative = false;

  321.             for (int i = 0; i < fpexp.length(); i++) {
  322.                 if (fpexp.charAt(i) == '-') {
  323.                     negative = true;
  324.                     continue;
  325.                 }
  326.                 if (fpexp.charAt(i) >= '0' && fpexp.charAt(i) <= '9') {
  327.                     sciexp = sciexp * 10 + fpexp.charAt(i) - '0';
  328.                 }
  329.             }

  330.             if (negative) {
  331.                 sciexp = -sciexp;
  332.             }
  333.         } else {
  334.             // normal case
  335.             fpdecimal = s;
  336.         }

  337.         // If there is a minus sign in the number then it is negative
  338.         if (fpdecimal.indexOf("-") !=  -1) {
  339.             sign = -1;
  340.         }

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

  343.         // Move p to first significant digit
  344.         int decimalPos = 0;
  345.         for (;;) {
  346.             if (fpdecimal.charAt(p) >= '1' && fpdecimal.charAt(p) <= '9') {
  347.                 break;
  348.             }

  349.             if (decimalFound && fpdecimal.charAt(p) == '0') {
  350.                 decimalPos--;
  351.             }

  352.             if (fpdecimal.charAt(p) == '.') {
  353.                 decimalFound = true;
  354.             }

  355.             p++;

  356.             if (p == fpdecimal.length()) {
  357.                 break;
  358.             }
  359.         }

  360.         // Copy the string onto Stripped
  361.         int q = offset;
  362.         striped[0] = '0';
  363.         striped[1] = '0';
  364.         striped[2] = '0';
  365.         striped[3] = '0';
  366.         int significantDigits = 0;
  367.         for (;;) {
  368.             if (p == (fpdecimal.length())) {
  369.                 break;
  370.             }

  371.             // Don't want to run pass the end of the array
  372.             if (q == mant.length * rsize + offset + 1) {
  373.                 break;
  374.             }

  375.             if (fpdecimal.charAt(p) == '.') {
  376.                 decimalFound = true;
  377.                 decimalPos = significantDigits;
  378.                 p++;
  379.                 continue;
  380.             }

  381.             if (fpdecimal.charAt(p) < '0' || fpdecimal.charAt(p) > '9') {
  382.                 p++;
  383.                 continue;
  384.             }

  385.             striped[q] = fpdecimal.charAt(p);
  386.             q++;
  387.             p++;
  388.             significantDigits++;
  389.         }


  390.         // If the decimal point has been found then get rid of trailing zeros.
  391.         if (decimalFound && q != offset) {
  392.             for (;;) {
  393.                 q--;
  394.                 if (q == offset) {
  395.                     break;
  396.                 }
  397.                 if (striped[q] == '0') {
  398.                     significantDigits--;
  399.                 } else {
  400.                     break;
  401.                 }
  402.             }
  403.         }

  404.         // special case of numbers like "0.00000"
  405.         if (decimalFound && significantDigits == 0) {
  406.             decimalPos = 0;
  407.         }

  408.         // Implicit decimal point at end of number if not present
  409.         if (!decimalFound) {
  410.             decimalPos = q - offset;
  411.         }

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

  415.         while (p > q) {
  416.             if (striped[p] != '0') {
  417.                 break;
  418.             }
  419.             p--;
  420.         }

  421.         // Make sure the decimal is on a mod 10000 boundary
  422.         int i = ((rsize * 100) - decimalPos - sciexp % rsize) % rsize;
  423.         q -= i;
  424.         decimalPos += i;

  425.         // Make the mantissa length right by adding zeros at the end if necessary
  426.         while ((p - q) < (mant.length * rsize)) {
  427.             for (i = 0; i < rsize; i++) {
  428.                 striped[++p] = '0';
  429.             }
  430.         }

  431.         // Ok, now we know how many trailing zeros there are,
  432.         // and where the least significant digit is
  433.         for (i = mant.length - 1; i >= 0; i--) {
  434.             mant[i] = (striped[q]     - '0') * 1000 +
  435.                       (striped[q + 1] - '0') * 100  +
  436.                       (striped[q + 2] - '0') * 10   +
  437.                       (striped[q + 3] - '0');
  438.             q += 4;
  439.         }


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

  441.         if (q < striped.length) {
  442.             // Is there possible another digit?
  443.             round((striped[q] - '0') * 1000);
  444.         }
  445.     }

  446.     /** Creates an instance with a non-finite value.
  447.      * @param field field to which this instance belongs
  448.      * @param sign sign of the Dfp to create
  449.      * @param nans code of the value, must be one of {@link #INFINITE},
  450.      * {@link #SNAN},  {@link #QNAN}
  451.      */
  452.     protected Dfp(final DfpField field, final byte sign, final byte nans) {
  453.         this.field = field;
  454.         this.mant    = new int[field.getRadixDigits()];
  455.         this.sign    = sign;
  456.         this.exp     = 0;
  457.         this.nans    = nans;
  458.     }

  459.     /** Create an instance with a value of 0.
  460.      * Use this internally in preference to constructors to facilitate subclasses
  461.      * @return a new instance with a value of 0
  462.      */
  463.     public Dfp newInstance() {
  464.         return new Dfp(getField());
  465.     }

  466.     /** Create an instance from a byte value.
  467.      * @param x value to convert to an instance
  468.      * @return a new instance with value x
  469.      */
  470.     public Dfp newInstance(final byte x) {
  471.         return new Dfp(getField(), x);
  472.     }

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

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

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

  494.     /** Create an instance by copying an existing one.
  495.      * Use this internally in preference to constructors to facilitate subclasses.
  496.      * @param d instance to copy
  497.      * @return a new instance with the same value as d
  498.      */
  499.     public Dfp newInstance(final Dfp d) {

  500.         // make sure we don't mix number with different precision
  501.         if (field.getRadixDigits() != d.field.getRadixDigits()) {
  502.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  503.             final Dfp result = newInstance(getZero());
  504.             result.nans = QNAN;
  505.             return dotrap(DfpField.FLAG_INVALID, NEW_INSTANCE_TRAP, d, result);
  506.         }

  507.         return new Dfp(d);
  508.     }

  509.     /** Create an instance from a String representation.
  510.      * Use this internally in preference to constructors to facilitate subclasses.
  511.      * @param s string representation of the instance
  512.      * @return a new instance parsed from specified string
  513.      */
  514.     public Dfp newInstance(final String s) {
  515.         return new Dfp(field, s);
  516.     }

  517.     /** Creates an instance with a non-finite value.
  518.      * @param sig sign of the Dfp to create
  519.      * @param code code of the value, must be one of {@link #INFINITE},
  520.      * {@link #SNAN},  {@link #QNAN}
  521.      * @return a new instance with a non-finite value
  522.      */
  523.     public Dfp newInstance(final byte sig, final byte code) {
  524.         return field.newDfp(sig, code);
  525.     }

  526.     /** Get the {@link org.apache.commons.math4.legacy.core.Field Field} (really a
  527.      * {@link DfpField}) to which the instance belongs.
  528.      * <p>
  529.      * The field is linked to the number of digits and acts as a factory
  530.      * for {@link Dfp} instances.
  531.      * </p>
  532.      * @return {@link org.apache.commons.math4.legacy.core.Field Field} (really a {@link DfpField}) to which the instance belongs
  533.      */
  534.     @Override
  535.     public DfpField getField() {
  536.         return field;
  537.     }

  538.     /** Get the number of radix digits of the instance.
  539.      * @return number of radix digits
  540.      */
  541.     public int getRadixDigits() {
  542.         return field.getRadixDigits();
  543.     }

  544.     /** Get the constant 0.
  545.      * @return a Dfp with value zero
  546.      */
  547.     public Dfp getZero() {
  548.         return field.getZero();
  549.     }

  550.     /** Get the constant 1.
  551.      * @return a Dfp with value one
  552.      */
  553.     public Dfp getOne() {
  554.         return field.getOne();
  555.     }

  556.     /** Get the constant 2.
  557.      * @return a Dfp with value two
  558.      */
  559.     public Dfp getTwo() {
  560.         return field.getTwo();
  561.     }

  562.     /** Shift the mantissa left, and adjust the exponent to compensate.
  563.      */
  564.     protected void shiftLeft() {
  565.         if (mant.length - 1 > 0) {
  566.             System.arraycopy(mant, 0, mant, 1, mant.length - 1);
  567.         }
  568.         mant[0] = 0;
  569.         exp--;
  570.     }

  571.     /* Note that shiftRight() does not call round() as that round() itself
  572.      uses shiftRight() */
  573.     /** Shift the mantissa right, and adjust the exponent to compensate.
  574.      */
  575.     protected void shiftRight() {
  576.         if (mant.length - 1 > 0) {
  577.             System.arraycopy(mant, 1, mant, 0, mant.length - 1);
  578.         }
  579.         mant[mant.length - 1] = 0;
  580.         exp++;
  581.     }

  582.     /** Make our exp equal to the supplied one, this may cause rounding.
  583.      *  Also causes de-normalized numbers.  These numbers are generally
  584.      *  dangerous because most routines assume normalized numbers.
  585.      *  Align doesn't round, so it will return the last digit destroyed
  586.      *  by shifting right.
  587.      *  @param e desired exponent
  588.      *  @return last digit destroyed by shifting right
  589.      */
  590.     protected int align(int e) {
  591.         int lostdigit = 0;
  592.         boolean inexact = false;

  593.         int diff = exp - e;

  594.         int adiff = diff;
  595.         if (adiff < 0) {
  596.             adiff = -adiff;
  597.         }

  598.         if (diff == 0) {
  599.             return 0;
  600.         }

  601.         if (adiff > (mant.length + 1)) {
  602.             // Special case
  603.             Arrays.fill(mant, 0);
  604.             exp = e;

  605.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  606.             dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this);

  607.             return 0;
  608.         }

  609.         for (int i = 0; i < adiff; i++) {
  610.             if (diff < 0) {
  611.                 /* Keep track of loss -- only signal inexact after losing 2 digits.
  612.                  * the first lost digit is returned to add() and may be incorporated
  613.                  * into the result.
  614.                  */
  615.                 if (lostdigit != 0) {
  616.                     inexact = true;
  617.                 }

  618.                 lostdigit = mant[0];

  619.                 shiftRight();
  620.             } else {
  621.                 shiftLeft();
  622.             }
  623.         }

  624.         if (inexact) {
  625.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  626.             dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this);
  627.         }

  628.         return lostdigit;
  629.     }

  630.     /** Check if instance is less than x.
  631.      * @param x number to check instance against
  632.      * @return true if instance is less than x and neither are NaN, false otherwise
  633.      */
  634.     public boolean lessThan(final Dfp x) {

  635.         // make sure we don't mix number with different precision
  636.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  637.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  638.             final Dfp result = newInstance(getZero());
  639.             result.nans = QNAN;
  640.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, result);
  641.             return false;
  642.         }

  643.         /* if a nan is involved, signal invalid and return false */
  644.         if (isNaN() || x.isNaN()) {
  645.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  646.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, newInstance(getZero()));
  647.             return false;
  648.         }

  649.         return compare(this, x) < 0;
  650.     }

  651.     /** Check if instance is greater than x.
  652.      * @param x number to check instance against
  653.      * @return true if instance is greater than x and neither are NaN, false otherwise
  654.      */
  655.     public boolean greaterThan(final Dfp x) {

  656.         // make sure we don't mix number with different precision
  657.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  658.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  659.             final Dfp result = newInstance(getZero());
  660.             result.nans = QNAN;
  661.             dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, result);
  662.             return false;
  663.         }

  664.         /* if a nan is involved, signal invalid and return false */
  665.         if (isNaN() || x.isNaN()) {
  666.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  667.             dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, newInstance(getZero()));
  668.             return false;
  669.         }

  670.         return compare(this, x) > 0;
  671.     }

  672.     /** Check if instance is less than or equal to 0.
  673.      * @return true if instance is not NaN and less than or equal to 0, false otherwise
  674.      */
  675.     public boolean negativeOrNull() {

  676.         if (isNaN()) {
  677.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  678.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  679.             return false;
  680.         }

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

  683.     /** Check if instance is strictly less than 0.
  684.      * @return true if instance is not NaN and less than or equal to 0, false otherwise
  685.      */
  686.     public boolean strictlyNegative() {

  687.         if (isNaN()) {
  688.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  689.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  690.             return false;
  691.         }

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

  694.     /** Check if instance is greater than or equal to 0.
  695.      * @return true if instance is not NaN and greater than or equal to 0, false otherwise
  696.      */
  697.     public boolean positiveOrNull() {

  698.         if (isNaN()) {
  699.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  700.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  701.             return false;
  702.         }

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

  705.     /** Check if instance is strictly greater than 0.
  706.      * @return true if instance is not NaN and greater than or equal to 0, false otherwise
  707.      */
  708.     public boolean strictlyPositive() {

  709.         if (isNaN()) {
  710.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  711.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  712.             return false;
  713.         }

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

  716.     /** Get the absolute value of instance.
  717.      * @return absolute value of instance
  718.      * @since 3.2
  719.      */
  720.     @Override
  721.     public Dfp abs() {
  722.         Dfp result = newInstance(this);
  723.         result.sign = 1;
  724.         return result;
  725.     }

  726.     /** Check if instance is infinite.
  727.      * @return true if instance is infinite
  728.      */
  729.     public boolean isInfinite() {
  730.         return nans == INFINITE;
  731.     }

  732.     /** Check if instance is not a number.
  733.      * @return true if instance is not a number
  734.      */
  735.     public boolean isNaN() {
  736.         return (nans == QNAN) || (nans == SNAN);
  737.     }

  738.     /** Check if instance is equal to zero.
  739.      * @return true if instance is equal to zero
  740.      */
  741.     public boolean isZero() {

  742.         if (isNaN()) {
  743.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  744.             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
  745.             return false;
  746.         }

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

  749.     /** Check if instance is equal to x.
  750.      * @param other object to check instance against
  751.      * @return true if instance is equal to x and neither are NaN, false otherwise
  752.      */
  753.     @Override
  754.     public boolean equals(final Object other) {

  755.         if (other instanceof Dfp) {
  756.             final Dfp x = (Dfp) other;
  757.             if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) {
  758.                 return false;
  759.             }

  760.             return compare(this, x) == 0;
  761.         }

  762.         return false;
  763.     }

  764.     /**
  765.      * Gets a hashCode for the instance.
  766.      * @return a hash code value for this object
  767.      */
  768.     @Override
  769.     public int hashCode() {
  770.         return 17 + (isZero() ? 0 : (sign << 8)) + (nans << 16) + exp + Arrays.hashCode(mant);
  771.     }

  772.     /** Check if instance is not equal to x.
  773.      * @param x number to check instance against
  774.      * @return true if instance is not equal to x and neither are NaN, false otherwise
  775.      */
  776.     public boolean unequal(final Dfp x) {
  777.         if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) {
  778.             return false;
  779.         }

  780.         return greaterThan(x) || lessThan(x);
  781.     }

  782.     /** Compare two instances.
  783.      * @param a first instance in comparison
  784.      * @param b second instance in comparison
  785.      * @return -1 if {@code a < b}, 1 if {@code a > b} and 0 if {@code a == b}
  786.      *  Note this method does not properly handle NaNs or numbers with different precision.
  787.      */
  788.     private static int compare(final Dfp a, final Dfp b) {
  789.         // Ignore the sign of zero
  790.         if (a.mant[a.mant.length - 1] == 0 && b.mant[b.mant.length - 1] == 0 &&
  791.             a.nans == FINITE && b.nans == FINITE) {
  792.             return 0;
  793.         }

  794.         if (a.sign != b.sign) {
  795.             if (a.sign == -1) {
  796.                 return -1;
  797.             } else {
  798.                 return 1;
  799.             }
  800.         }

  801.         // deal with the infinities
  802.         if (a.nans == INFINITE && b.nans == FINITE) {
  803.             return a.sign;
  804.         }

  805.         if (a.nans == FINITE && b.nans == INFINITE) {
  806.             return -b.sign;
  807.         }

  808.         if (a.nans == INFINITE && b.nans == INFINITE) {
  809.             return 0;
  810.         }

  811.         // Handle special case when a or b is zero, by ignoring the exponents
  812.         if (b.mant[b.mant.length - 1] != 0 && a.mant[b.mant.length - 1] != 0) {
  813.             if (a.exp < b.exp) {
  814.                 return -a.sign;
  815.             }

  816.             if (a.exp > b.exp) {
  817.                 return a.sign;
  818.             }
  819.         }

  820.         // compare the mantissas
  821.         for (int i = a.mant.length - 1; i >= 0; i--) {
  822.             if (a.mant[i] > b.mant[i]) {
  823.                 return a.sign;
  824.             }

  825.             if (a.mant[i] < b.mant[i]) {
  826.                 return -a.sign;
  827.             }
  828.         }

  829.         return 0;
  830.     }

  831.     /** Round to nearest integer using the round-half-even method.
  832.      *  That is round to nearest integer unless both are equidistant.
  833.      *  In which case round to the even one.
  834.      *  @return rounded value
  835.      * @since 3.2
  836.      */
  837.     @Override
  838.     public Dfp rint() {
  839.         return trunc(DfpField.RoundingMode.ROUND_HALF_EVEN);
  840.     }

  841.     /** Round to an integer using the round floor mode.
  842.      * That is, round toward -Infinity
  843.      *  @return rounded value
  844.      * @since 3.2
  845.      */
  846.     @Override
  847.     public Dfp floor() {
  848.         return trunc(DfpField.RoundingMode.ROUND_FLOOR);
  849.     }

  850.     /** Round to an integer using the round ceil mode.
  851.      * That is, round toward +Infinity
  852.      *  @return rounded value
  853.      * @since 3.2
  854.      */
  855.     @Override
  856.     public Dfp ceil() {
  857.         return trunc(DfpField.RoundingMode.ROUND_CEIL);
  858.     }

  859.     /** Returns the IEEE remainder.
  860.      * @param d divisor
  861.      * @return this less n &times; d, where n is the integer closest to this/d
  862.      * @since 3.2
  863.      */
  864.     @Override
  865.     public Dfp remainder(final Dfp d) {

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

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

  871.         return result;
  872.     }

  873.     /** Does the integer conversions with the specified rounding.
  874.      * @param rmode rounding mode to use
  875.      * @return truncated value
  876.      */
  877.     protected Dfp trunc(final DfpField.RoundingMode rmode) {
  878.         boolean changed = false;

  879.         if (isNaN()) {
  880.             return newInstance(this);
  881.         }

  882.         if (nans == INFINITE) {
  883.             return newInstance(this);
  884.         }

  885.         if (mant[mant.length - 1] == 0) {
  886.             // a is zero
  887.             return newInstance(this);
  888.         }

  889.         /* If the exponent is less than zero then we can certainly
  890.          * return zero */
  891.         if (exp < 0) {
  892.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  893.             Dfp result = newInstance(getZero());
  894.             result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
  895.             return result;
  896.         }

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

  900.         if (exp >= mant.length) {
  901.             return newInstance(this);
  902.         }

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

  905.         Dfp result = newInstance(this);
  906.         for (int i = 0; i < mant.length - result.exp; i++) {
  907.             changed |= result.mant[i] != 0;
  908.             result.mant[i] = 0;
  909.         }

  910.         if (changed) {
  911.             switch (rmode) {
  912.             case ROUND_FLOOR:
  913.                 if (result.sign == -1) {
  914.                     // then we must increment the mantissa by one
  915.                     result = result.add(newInstance(-1));
  916.                 }
  917.                 break;

  918.             case ROUND_CEIL:
  919.                 if (result.sign == 1) {
  920.                     // then we must increment the mantissa by one
  921.                     result = result.add(getOne());
  922.                 }
  923.                 break;

  924.             case ROUND_HALF_EVEN:
  925.             default:
  926.                 final Dfp half = newInstance("0.5");
  927.                 Dfp a = subtract(result);  // difference between this and result
  928.                 a.sign = 1;            // force positive (take abs)
  929.                 if (a.greaterThan(half)) {
  930.                     a = newInstance(getOne());
  931.                     a.sign = sign;
  932.                     result = result.add(a);
  933.                 }

  934.                 /* If exactly equal to 1/2 and odd then increment */
  935.                 if (a.equals(half) && result.exp > 0 && (result.mant[mant.length - result.exp] & 1) != 0) {
  936.                     a = newInstance(getOne());
  937.                     a.sign = sign;
  938.                     result = result.add(a);
  939.                 }
  940.                 break;
  941.             }

  942.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);  // signal inexact
  943.             result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
  944.             return result;
  945.         }

  946.         return result;
  947.     }

  948.     /** Convert this to an integer.
  949.      * If greater than 2147483647, it returns 2147483647. If less than -2147483648 it returns -2147483648.
  950.      * @return converted number
  951.      */
  952.     public int intValue() {
  953.         Dfp rounded;
  954.         int result = 0;

  955.         rounded = rint();

  956.         if (rounded.greaterThan(newInstance(2147483647))) {
  957.             return 2147483647;
  958.         }

  959.         if (rounded.lessThan(newInstance(-2147483648))) {
  960.             return -2147483648;
  961.         }

  962.         for (int i = mant.length - 1; i >= mant.length - rounded.exp; i--) {
  963.             result = result * RADIX + rounded.mant[i];
  964.         }

  965.         if (rounded.sign == -1) {
  966.             result = -result;
  967.         }

  968.         return result;
  969.     }

  970.     /** Get the exponent of the greatest power of 10000 that is
  971.      *  less than or equal to the absolute value of this.  I.E.  if
  972.      *  this is 10<sup>6</sup> then log10K would return 1.
  973.      *  @return integer base 10000 logarithm
  974.      */
  975.     public int log10K() {
  976.         return exp - 1;
  977.     }

  978.     /** Get the specified  power of 10000.
  979.      * @param e desired power
  980.      * @return 10000<sup>e</sup>
  981.      */
  982.     public Dfp power10K(final int e) {
  983.         Dfp d = newInstance(getOne());
  984.         d.exp = e + 1;
  985.         return d;
  986.     }

  987.     /** Get the exponent of the greatest power of 10 that is less than or equal to abs(this).
  988.      *  @return integer base 10 logarithm
  989.      * @since 3.2
  990.      */
  991.     public int intLog10()  {
  992.         if (mant[mant.length - 1] > 1000) {
  993.             return exp * 4 - 1;
  994.         }
  995.         if (mant[mant.length - 1] > 100) {
  996.             return exp * 4 - 2;
  997.         }
  998.         if (mant[mant.length - 1] > 10) {
  999.             return exp * 4 - 3;
  1000.         }
  1001.         return exp * 4 - 4;
  1002.     }

  1003.     /** Return the specified  power of 10.
  1004.      * @param e desired power
  1005.      * @return 10<sup>e</sup>
  1006.      */
  1007.     public Dfp power10(final int e) {
  1008.         Dfp d = newInstance(getOne());

  1009.         if (e >= 0) {
  1010.             d.exp = e / 4 + 1;
  1011.         } else {
  1012.             d.exp = (e + 1) / 4;
  1013.         }

  1014.         switch ((e % 4 + 4) % 4) {
  1015.         case 0:
  1016.             break;
  1017.         case 1:
  1018.             d = d.multiply(10);
  1019.             break;
  1020.         case 2:
  1021.             d = d.multiply(100);
  1022.             break;
  1023.         default:
  1024.             d = d.multiply(1000);
  1025.         }

  1026.         return d;
  1027.     }

  1028.     /** Negate the mantissa of this by computing the complement.
  1029.      *  Leaves the sign bit unchanged, used internally by add.
  1030.      *  Denormalized numbers are handled properly here.
  1031.      *  @param extra ???
  1032.      *  @return ???
  1033.      */
  1034.     protected int complement(int extra) {

  1035.         extra = RADIX - extra;
  1036.         for (int i = 0; i < mant.length; i++) {
  1037.             mant[i] = RADIX - mant[i] - 1;
  1038.         }

  1039.         int rh = extra / RADIX;
  1040.         extra -= rh * RADIX;
  1041.         for (int i = 0; i < mant.length; i++) {
  1042.             final int r = mant[i] + rh;
  1043.             rh = r / RADIX;
  1044.             mant[i] = r - rh * RADIX;
  1045.         }

  1046.         return extra;
  1047.     }

  1048.     /** Add x to this.
  1049.      * @param x number to add
  1050.      * @return sum of this and x
  1051.      */
  1052.     @Override
  1053.     public Dfp add(final Dfp x) {

  1054.         // make sure we don't mix number with different precision
  1055.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  1056.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1057.             final Dfp result = newInstance(getZero());
  1058.             result.nans = QNAN;
  1059.             return dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result);
  1060.         }

  1061.         /* handle special cases */
  1062.         if (nans != FINITE || x.nans != FINITE) {
  1063.             if (isNaN()) {
  1064.                 return this;
  1065.             }

  1066.             if (x.isNaN()) {
  1067.                 return x;
  1068.             }

  1069.             if (nans == INFINITE && x.nans == FINITE) {
  1070.                 return this;
  1071.             }

  1072.             if (x.nans == INFINITE && nans == FINITE) {
  1073.                 return x;
  1074.             }

  1075.             if (x.nans == INFINITE && nans == INFINITE && sign == x.sign) {
  1076.                 return x;
  1077.             }

  1078.             if (x.nans == INFINITE && nans == INFINITE && sign != x.sign) {
  1079.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1080.                 Dfp result = newInstance(getZero());
  1081.                 result.nans = QNAN;
  1082.                 result = dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result);
  1083.                 return result;
  1084.             }
  1085.         }

  1086.         /* copy this and the arg */
  1087.         Dfp a = newInstance(this);
  1088.         Dfp b = newInstance(x);

  1089.         /* initialize the result object */
  1090.         Dfp result = newInstance(getZero());

  1091.         /* Make all numbers positive, but remember their sign */
  1092.         final byte asign = a.sign;
  1093.         final byte bsign = b.sign;

  1094.         a.sign = 1;
  1095.         b.sign = 1;

  1096.         /* The result will be signed like the arg with greatest magnitude */
  1097.         byte rsign = bsign;
  1098.         if (compare(a, b) > 0) {
  1099.             rsign = asign;
  1100.         }

  1101.         /*
  1102.          * Handle special case when a or b is zero, by setting the exponent of the zero
  1103.          * number equal to the other one. This avoids an alignment which would cause
  1104.          * catastropic loss of precision
  1105.          */
  1106.         if (b.mant[mant.length - 1] == 0) {
  1107.             b.exp = a.exp;
  1108.         }

  1109.         if (a.mant[mant.length - 1] == 0) {
  1110.             a.exp = b.exp;
  1111.         }

  1112.         /* align number with the smaller exponent */
  1113.         int aextradigit = 0;
  1114.         int bextradigit = 0;
  1115.         if (a.exp < b.exp) {
  1116.             aextradigit = a.align(b.exp);
  1117.         } else {
  1118.             bextradigit = b.align(a.exp);
  1119.         }

  1120.         /* complement the smaller of the two if the signs are different */
  1121.         if (asign != bsign) {
  1122.             if (asign == rsign) {
  1123.                 bextradigit = b.complement(bextradigit);
  1124.             } else {
  1125.                 aextradigit = a.complement(aextradigit);
  1126.             }
  1127.         }

  1128.         /* add the mantissas */
  1129.         int rh = 0; /* acts as a carry */
  1130.         for (int i = 0; i < mant.length; i++) {
  1131.             final int r = a.mant[i] + b.mant[i] + rh;
  1132.             rh = r / RADIX;
  1133.             result.mant[i] = r - rh * RADIX;
  1134.         }
  1135.         result.exp = a.exp;
  1136.         result.sign = rsign;

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

  1139.         if (rh != 0 && (asign == bsign)) {
  1140.             final int lostdigit = result.mant[0];
  1141.             result.shiftRight();
  1142.             result.mant[mant.length - 1] = rh;
  1143.             final int excp = result.round(lostdigit);
  1144.             if (excp != 0) {
  1145.                 result = dotrap(excp, ADD_TRAP, x, result);
  1146.             }
  1147.         }

  1148.         /* normalize the result */
  1149.         for (int i = 0; i < mant.length; i++) {
  1150.             if (result.mant[mant.length - 1] != 0) {
  1151.                 break;
  1152.             }
  1153.             result.shiftLeft();
  1154.             if (i == 0) {
  1155.                 result.mant[0] = aextradigit + bextradigit;
  1156.                 aextradigit = 0;
  1157.                 bextradigit = 0;
  1158.             }
  1159.         }

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

  1163.             if (asign != bsign) {
  1164.                 // Unless adding 2 negative zeros, sign is positive
  1165.                 result.sign = 1;  // Per IEEE 854-1987 Section 6.3
  1166.             }
  1167.         }

  1168.         /* Call round to test for over/under flows */
  1169.         final int excp = result.round(aextradigit + bextradigit);
  1170.         if (excp != 0) {
  1171.             result = dotrap(excp, ADD_TRAP, x, result);
  1172.         }

  1173.         return result;
  1174.     }

  1175.     /** Returns a number that is this number with the sign bit reversed.
  1176.      * @return the opposite of this
  1177.      */
  1178.     @Override
  1179.     public Dfp negate() {
  1180.         Dfp result = newInstance(this);
  1181.         result.sign = (byte) -result.sign;
  1182.         return result;
  1183.     }

  1184.     /** Subtract x from this.
  1185.      * @param x number to subtract
  1186.      * @return difference of this and a
  1187.      */
  1188.     @Override
  1189.     public Dfp subtract(final Dfp x) {
  1190.         return add(x.negate());
  1191.     }

  1192.     /** Round this given the next digit n using the current rounding mode.
  1193.      * @param n ???
  1194.      * @return the IEEE flag if an exception occurred
  1195.      */
  1196.     protected int round(int n) {
  1197.         boolean inc = false;
  1198.         switch (field.getRoundingMode()) {
  1199.         case ROUND_DOWN:
  1200.             inc = false;
  1201.             break;

  1202.         case ROUND_UP:
  1203.             inc = n != 0;       // round up if n!=0
  1204.             break;

  1205.         case ROUND_HALF_UP:
  1206.             inc = n >= 5000;  // round half up
  1207.             break;

  1208.         case ROUND_HALF_DOWN:
  1209.             inc = n > 5000;  // round half down
  1210.             break;

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

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

  1217.         case ROUND_CEIL:
  1218.             inc = sign == 1 && n != 0;  // round ceil
  1219.             break;

  1220.         case ROUND_FLOOR:
  1221.         default:
  1222.             inc = sign == -1 && n != 0;  // round floor
  1223.             break;
  1224.         }

  1225.         if (inc) {
  1226.             // increment if necessary
  1227.             int rh = 1;
  1228.             for (int i = 0; i < mant.length; i++) {
  1229.                 final int r = mant[i] + rh;
  1230.                 rh = r / RADIX;
  1231.                 mant[i] = r - rh * RADIX;
  1232.             }

  1233.             if (rh != 0) {
  1234.                 shiftRight();
  1235.                 mant[mant.length - 1] = rh;
  1236.             }
  1237.         }

  1238.         // check for exceptional cases and raise signals if necessary
  1239.         if (exp < MIN_EXP) {
  1240.             // Gradual Underflow
  1241.             field.setIEEEFlagsBits(DfpField.FLAG_UNDERFLOW);
  1242.             return DfpField.FLAG_UNDERFLOW;
  1243.         }

  1244.         if (exp > MAX_EXP) {
  1245.             // Overflow
  1246.             field.setIEEEFlagsBits(DfpField.FLAG_OVERFLOW);
  1247.             return DfpField.FLAG_OVERFLOW;
  1248.         }

  1249.         if (n != 0) {
  1250.             // Inexact
  1251.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  1252.             return DfpField.FLAG_INEXACT;
  1253.         }

  1254.         return 0;
  1255.     }

  1256.     /** Multiply this by x.
  1257.      * @param x multiplicand
  1258.      * @return product of this and x
  1259.      */
  1260.     @Override
  1261.     public Dfp multiply(final Dfp x) {

  1262.         // make sure we don't mix number with different precision
  1263.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  1264.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1265.             final Dfp result = newInstance(getZero());
  1266.             result.nans = QNAN;
  1267.             return dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result);
  1268.         }

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

  1270.         /* handle special cases */
  1271.         if (nans != FINITE || x.nans != FINITE) {
  1272.             if (isNaN()) {
  1273.                 return this;
  1274.             }

  1275.             if (x.isNaN()) {
  1276.                 return x;
  1277.             }

  1278.             if (nans == INFINITE && x.nans == FINITE && x.mant[mant.length - 1] != 0) {
  1279.                 result = newInstance(this);
  1280.                 result.sign = (byte) (sign * x.sign);
  1281.                 return result;
  1282.             }

  1283.             if (x.nans == INFINITE && nans == FINITE && mant[mant.length - 1] != 0) {
  1284.                 result = newInstance(x);
  1285.                 result.sign = (byte) (sign * x.sign);
  1286.                 return result;
  1287.             }

  1288.             if (x.nans == INFINITE && nans == INFINITE) {
  1289.                 result = newInstance(this);
  1290.                 result.sign = (byte) (sign * x.sign);
  1291.                 return result;
  1292.             }

  1293.             if ((x.nans == INFINITE && nans == FINITE && mant[mant.length - 1] == 0) ||
  1294.                 (nans == INFINITE && x.nans == FINITE && x.mant[mant.length - 1] == 0)) {
  1295.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1296.                 result = newInstance(getZero());
  1297.                 result.nans = QNAN;
  1298.                 result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result);
  1299.                 return result;
  1300.             }
  1301.         }

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

  1303.         for (int i = 0; i < mant.length; i++) {
  1304.             int rh = 0; // acts as a carry
  1305.             for (int j = 0; j < mant.length; j++) {
  1306.                 int r = mant[i] * x.mant[j]; // multiply the 2 digits
  1307.                 r += product[i + j] + rh; // add to the product digit with carry in

  1308.                 rh = r / RADIX;
  1309.                 product[i + j] = r - rh * RADIX;
  1310.             }
  1311.             product[i + mant.length] = rh;
  1312.         }

  1313.         // Find the most sig digit
  1314.         int md = mant.length * 2 - 1;  // default, in case result is zero
  1315.         for (int i = mant.length * 2 - 1; i >= 0; i--) {
  1316.             if (product[i] != 0) {
  1317.                 md = i;
  1318.                 break;
  1319.             }
  1320.         }

  1321.         // Copy the digits into the result
  1322.         for (int i = 0; i < mant.length; i++) {
  1323.             result.mant[mant.length - i - 1] = product[md - i];
  1324.         }

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

  1328.         if (result.mant[mant.length - 1] == 0) {
  1329.             // if result is zero, set exp to zero
  1330.             result.exp = 0;
  1331.         }

  1332.         final int excp;
  1333.         if (md > (mant.length - 1)) {
  1334.             excp = result.round(product[md - mant.length]);
  1335.         } else {
  1336.             excp = result.round(0); // has no effect except to check status
  1337.         }

  1338.         if (excp != 0) {
  1339.             result = dotrap(excp, MULTIPLY_TRAP, x, result);
  1340.         }

  1341.         return result;
  1342.     }

  1343.     /** Multiply this by a single digit x.
  1344.      * @param x multiplicand
  1345.      * @return product of this and x
  1346.      */
  1347.     @Override
  1348.     public Dfp multiply(final int x) {
  1349.         if (x >= 0 && x < RADIX) {
  1350.             return multiplyFast(x);
  1351.         } else {
  1352.             return multiply(newInstance(x));
  1353.         }
  1354.     }

  1355.     /** Multiply this by a single digit 0&lt;=x&lt;radix.
  1356.      * There are speed advantages in this special case.
  1357.      * @param x multiplicand
  1358.      * @return product of this and x
  1359.      */
  1360.     private Dfp multiplyFast(final int x) {
  1361.         Dfp result = newInstance(this);

  1362.         /* handle special cases */
  1363.         if (nans != FINITE) {
  1364.             if (isNaN()) {
  1365.                 return this;
  1366.             }

  1367.             if (nans == INFINITE && x != 0) {
  1368.                 result = newInstance(this);
  1369.                 return result;
  1370.             }

  1371.             if (nans == INFINITE && x == 0) {
  1372.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1373.                 result = newInstance(getZero());
  1374.                 result.nans = QNAN;
  1375.                 result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, newInstance(getZero()), result);
  1376.                 return result;
  1377.             }
  1378.         }

  1379.         /* range check x */
  1380.         if (x < 0 || x >= RADIX) {
  1381.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1382.             result = newInstance(getZero());
  1383.             result.nans = QNAN;
  1384.             result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, result, result);
  1385.             return result;
  1386.         }

  1387.         int rh = 0;
  1388.         for (int i = 0; i < mant.length; i++) {
  1389.             final int r = mant[i] * x + rh;
  1390.             rh = r / RADIX;
  1391.             result.mant[i] = r - rh * RADIX;
  1392.         }

  1393.         int lostdigit = 0;
  1394.         if (rh != 0) {
  1395.             lostdigit = result.mant[0];
  1396.             result.shiftRight();
  1397.             result.mant[mant.length - 1] = rh;
  1398.         }

  1399.         if (result.mant[mant.length - 1] == 0) { // if result is zero, set exp to zero
  1400.             result.exp = 0;
  1401.         }

  1402.         final int excp = result.round(lostdigit);
  1403.         if (excp != 0) {
  1404.             result = dotrap(excp, MULTIPLY_TRAP, result, result);
  1405.         }

  1406.         return result;
  1407.     }

  1408.     /** Divide this by divisor.
  1409.      * @param divisor divisor
  1410.      * @return quotient of this by divisor
  1411.      */
  1412.     @Override
  1413.     public Dfp divide(Dfp divisor) {
  1414.         int[] dividend;  // current status of the dividend
  1415.         int[] quotient;  // quotient
  1416.         int[] remainder; // remainder
  1417.         int qd;          // current quotient digit we're working with
  1418.         int nsqd;        // number of significant quotient digits we have
  1419.         int trial = 0;   // trial quotient digit
  1420.         int minadj;      // minimum adjustment
  1421.         boolean trialgood; // Flag to indicate a good trail digit
  1422.         int md = 0;      // most sig digit in result
  1423.         int excp;        // exceptions

  1424.         // make sure we don't mix number with different precision
  1425.         if (field.getRadixDigits() != divisor.field.getRadixDigits()) {
  1426.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1427.             final Dfp result = newInstance(getZero());
  1428.             result.nans = QNAN;
  1429.             return dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result);
  1430.         }

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

  1432.         /* handle special cases */
  1433.         if (nans != FINITE || divisor.nans != FINITE) {
  1434.             if (isNaN()) {
  1435.                 return this;
  1436.             }

  1437.             if (divisor.isNaN()) {
  1438.                 return divisor;
  1439.             }

  1440.             if (nans == INFINITE && divisor.nans == FINITE) {
  1441.                 result = newInstance(this);
  1442.                 result.sign = (byte) (sign * divisor.sign);
  1443.                 return result;
  1444.             }

  1445.             if (divisor.nans == INFINITE && nans == FINITE) {
  1446.                 result = newInstance(getZero());
  1447.                 result.sign = (byte) (sign * divisor.sign);
  1448.                 return result;
  1449.             }

  1450.             if (divisor.nans == INFINITE && nans == INFINITE) {
  1451.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1452.                 result = newInstance(getZero());
  1453.                 result.nans = QNAN;
  1454.                 result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result);
  1455.                 return result;
  1456.             }
  1457.         }

  1458.         /* Test for divide by zero */
  1459.         if (divisor.mant[mant.length - 1] == 0) {
  1460.             field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO);
  1461.             result = newInstance(getZero());
  1462.             result.sign = (byte) (sign * divisor.sign);
  1463.             result.nans = INFINITE;
  1464.             result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, divisor, result);
  1465.             return result;
  1466.         }

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

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

  1471.         dividend[mant.length] = 0;
  1472.         quotient[mant.length] = 0;
  1473.         quotient[mant.length + 1] = 0;
  1474.         remainder[mant.length] = 0;

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

  1476.         for (int i = 0; i < mant.length; i++) {
  1477.             dividend[i] = mant[i];
  1478.             quotient[i] = 0;
  1479.             remainder[i] = 0;
  1480.         }

  1481.         /* outer loop.  Once per quotient digit */
  1482.         nsqd = 0;
  1483.         for (qd = mant.length + 1; qd >= 0; qd--) {
  1484.             /* Determine outer limits of our quotient digit */

  1485.             // r =  most sig 2 digits of dividend
  1486.             final int divMsb = dividend[mant.length] * RADIX + dividend[mant.length - 1];
  1487.             int min = divMsb / (divisor.mant[mant.length - 1] + 1);
  1488.             int max = (divMsb + 1) / divisor.mant[mant.length - 1];

  1489.             trialgood = false;
  1490.             while (!trialgood) {
  1491.                 // try the mean
  1492.                 trial = (min + max) / 2;

  1493.                 /* Multiply by divisor and store as remainder */
  1494.                 int rh = 0;
  1495.                 for (int i = 0; i < mant.length + 1; i++) {
  1496.                     int dm = (i < mant.length) ? divisor.mant[i] : 0;
  1497.                     final int r = (dm * trial) + rh;
  1498.                     rh = r / RADIX;
  1499.                     remainder[i] = r - rh * RADIX;
  1500.                 }

  1501.                 /* subtract the remainder from the dividend */
  1502.                 rh = 1; // carry in to aid the subtraction
  1503.                 for (int i = 0; i < mant.length + 1; i++) {
  1504.                     final int r = ((RADIX - 1) - remainder[i]) + dividend[i] + rh;
  1505.                     rh = r / RADIX;
  1506.                     remainder[i] = r - rh * RADIX;
  1507.                 }

  1508.                 /* Lets analyze what we have here */
  1509.                 if (rh == 0) {
  1510.                     // trial is too big -- negative remainder
  1511.                     max = trial - 1;
  1512.                     continue;
  1513.                 }

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

  1517.                 if (minadj >= 2) {
  1518.                     min = trial + minadj; // update the minimum
  1519.                     continue;
  1520.                 }

  1521.                 /* May have a good one here, check more thoroughly. Basically its a good
  1522.                  * one if it is less than the divisor */
  1523.                 trialgood = false;  // assume false
  1524.                 for (int i = mant.length - 1; i >= 0; i--) {
  1525.                     if (divisor.mant[i] > remainder[i]) {
  1526.                         trialgood = true;
  1527.                         break;
  1528.                     }
  1529.                     if (divisor.mant[i] < remainder[i]) {
  1530.                         break;
  1531.                     }
  1532.                 }

  1533.                 if (remainder[mant.length] != 0) {
  1534.                     trialgood = false;
  1535.                 }

  1536.                 if (!trialgood) {
  1537.                     min = trial + 1;
  1538.                 }
  1539.             }

  1540.             /* Great we have a digit! */
  1541.             quotient[qd] = trial;
  1542.             if (trial != 0 || nsqd != 0) {
  1543.                 nsqd++;
  1544.             }

  1545.             if (field.getRoundingMode() == DfpField.RoundingMode.ROUND_DOWN && nsqd == mant.length) {
  1546.                 // We have enough for this mode
  1547.                 break;
  1548.             }

  1549.             if (nsqd > mant.length) {
  1550.                 // We have enough digits
  1551.                 break;
  1552.             }

  1553.             /* move the remainder into the dividend while left shifting */
  1554.             dividend[0] = 0;
  1555.             System.arraycopy(remainder, 0, dividend, 1, mant.length);
  1556.         }

  1557.         /* Find the most sig digit */
  1558.         md = mant.length;  // default
  1559.         for (int i = mant.length + 1; i >= 0; i--) {
  1560.             if (quotient[i] != 0) {
  1561.                 md = i;
  1562.                 break;
  1563.             }
  1564.         }

  1565.         /* Copy the digits into the result */
  1566.         for (int i = 0; i < mant.length; i++) {
  1567.             result.mant[mant.length - i - 1] = quotient[md - i];
  1568.         }

  1569.         /* Fixup the exponent. */
  1570.         result.exp = exp - divisor.exp + md - mant.length;
  1571.         result.sign = (byte) ((sign == divisor.sign) ? 1 : -1);

  1572.         if (result.mant[mant.length - 1] == 0) { // if result is zero, set exp to zero
  1573.             result.exp = 0;
  1574.         }

  1575.         if (md > (mant.length - 1)) {
  1576.             excp = result.round(quotient[md - mant.length]);
  1577.         } else {
  1578.             excp = result.round(0);
  1579.         }

  1580.         if (excp != 0) {
  1581.             result = dotrap(excp, DIVIDE_TRAP, divisor, result);
  1582.         }

  1583.         return result;
  1584.     }

  1585.     /** Divide by a single digit less than radix.
  1586.      *  Special case, so there are speed advantages. 0 &lt;= divisor &lt; radix
  1587.      * @param divisor divisor
  1588.      * @return quotient of this by divisor
  1589.      */
  1590.     public Dfp divide(int divisor) {

  1591.         // Handle special cases
  1592.         if (nans != FINITE) {
  1593.             if (isNaN()) {
  1594.                 return this;
  1595.             }

  1596.             if (nans == INFINITE) {
  1597.                 return newInstance(this);
  1598.             }
  1599.         }

  1600.         // Test for divide by zero
  1601.         if (divisor == 0) {
  1602.             field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO);
  1603.             Dfp result = newInstance(getZero());
  1604.             result.sign = sign;
  1605.             result.nans = INFINITE;
  1606.             result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, getZero(), result);
  1607.             return result;
  1608.         }

  1609.         // range check divisor
  1610.         if (divisor < 0 || divisor >= RADIX) {
  1611.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1612.             Dfp result = newInstance(getZero());
  1613.             result.nans = QNAN;
  1614.             result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, result, result);
  1615.             return result;
  1616.         }

  1617.         Dfp result = newInstance(this);

  1618.         int rl = 0;
  1619.         for (int i = mant.length - 1; i >= 0; i--) {
  1620.             final int r = rl * RADIX + result.mant[i];
  1621.             final int rh = r / divisor;
  1622.             rl = r - rh * divisor;
  1623.             result.mant[i] = rh;
  1624.         }

  1625.         if (result.mant[mant.length - 1] == 0) {
  1626.             // normalize
  1627.             result.shiftLeft();
  1628.             final int r = rl * RADIX;        // compute the next digit and put it in
  1629.             final int rh = r / divisor;
  1630.             rl = r - rh * divisor;
  1631.             result.mant[0] = rh;
  1632.         }

  1633.         final int excp = result.round(rl * RADIX / divisor);  // do the rounding
  1634.         if (excp != 0) {
  1635.             result = dotrap(excp, DIVIDE_TRAP, result, result);
  1636.         }

  1637.         return result;
  1638.     }

  1639.     /** {@inheritDoc} */
  1640.     @Override
  1641.     public Dfp reciprocal() {
  1642.         return field.getOne().divide(this);
  1643.     }

  1644.     /** Compute the square root.
  1645.      * @return square root of the instance
  1646.      * @since 3.2
  1647.      */
  1648.     @Override
  1649.     public Dfp sqrt() {

  1650.         // check for unusual cases
  1651.         if (nans == FINITE && mant[mant.length - 1] == 0) {
  1652.             // if zero
  1653.             return newInstance(this);
  1654.         }

  1655.         if (nans != FINITE) {
  1656.             if (nans == INFINITE && sign == 1) {
  1657.                 // if positive infinity
  1658.                 return newInstance(this);
  1659.             }

  1660.             if (nans == QNAN) {
  1661.                 return newInstance(this);
  1662.             }

  1663.             if (nans == SNAN) {
  1664.                 Dfp result;

  1665.                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1666.                 result = newInstance(this);
  1667.                 result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result);
  1668.                 return result;
  1669.             }
  1670.         }

  1671.         if (sign == -1) {
  1672.             // if negative
  1673.             Dfp result;

  1674.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1675.             result = newInstance(this);
  1676.             result.nans = QNAN;
  1677.             result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result);
  1678.             return result;
  1679.         }

  1680.         Dfp x = newInstance(this);

  1681.         /* Lets make a reasonable guess as to the size of the square root */
  1682.         if (x.exp < -1 || x.exp > 1) {
  1683.             x.exp = this.exp / 2;
  1684.         }

  1685.         /* Coarsely estimate the mantissa */
  1686.         switch (x.mant[mant.length - 1] / 2000) {
  1687.         case 0:
  1688.             x.mant[mant.length - 1] = x.mant[mant.length - 1] / 2 + 1;
  1689.             break;
  1690.         case 2:
  1691.             x.mant[mant.length - 1] = 1500;
  1692.             break;
  1693.         case 3:
  1694.             x.mant[mant.length - 1] = 2200;
  1695.             break;
  1696.         default:
  1697.             x.mant[mant.length - 1] = 3000;
  1698.         }

  1699.         Dfp dx = newInstance(x);

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

  1702.         Dfp px  = getZero();
  1703.         Dfp ppx = getZero();
  1704.         while (x.unequal(px)) {
  1705.             dx = newInstance(x);
  1706.             dx.sign = -1;
  1707.             dx = dx.add(this.divide(x));
  1708.             dx = dx.divide(2);
  1709.             ppx = px;
  1710.             px = x;
  1711.             x = x.add(dx);

  1712.             if (x.equals(ppx)) {
  1713.                 // alternating between two values
  1714.                 break;
  1715.             }

  1716.             // if dx is zero, break.  Note testing the most sig digit
  1717.             // is a sufficient test since dx is normalized
  1718.             if (dx.mant[mant.length - 1] == 0) {
  1719.                 break;
  1720.             }
  1721.         }

  1722.         return x;
  1723.     }

  1724.     /** Get a string representation of the instance.
  1725.      * @return string representation of the instance
  1726.      */
  1727.     @Override
  1728.     public String toString() {
  1729.         if (nans != FINITE) {
  1730.             // if non-finite exceptional cases
  1731.             if (nans == INFINITE) {
  1732.                 return (sign < 0) ? NEG_INFINITY_STRING : POS_INFINITY_STRING;
  1733.             } else {
  1734.                 return NAN_STRING;
  1735.             }
  1736.         }

  1737.         if (exp > mant.length || exp < -1) {
  1738.             return dfp2sci();
  1739.         }

  1740.         return dfp2string();
  1741.     }

  1742.     /** Convert an instance to a string using scientific notation.
  1743.      * @return string representation of the instance in scientific notation
  1744.      */
  1745.     protected String dfp2sci() {
  1746.         char[] rawdigits    = new char[mant.length * 4];
  1747.         char[] outputbuffer = new char[mant.length * 4 + 20];
  1748.         int p;
  1749.         int q;
  1750.         int e;
  1751.         int ae;
  1752.         int shf;

  1753.         // Get all the digits
  1754.         p = 0;
  1755.         for (int i = mant.length - 1; i >= 0; i--) {
  1756.             rawdigits[p++] = (char) ((mant[i] / 1000) + '0');
  1757.             rawdigits[p++] = (char) (((mant[i] / 100) % 10) + '0');
  1758.             rawdigits[p++] = (char) (((mant[i] / 10) % 10) + '0');
  1759.             rawdigits[p++] = (char) (((mant[i]) % 10) + '0');
  1760.         }

  1761.         // Find the first non-zero one
  1762.         for (p = 0; p < rawdigits.length; p++) {
  1763.             if (rawdigits[p] != '0') {
  1764.                 break;
  1765.             }
  1766.         }
  1767.         shf = p;

  1768.         // Now do the conversion
  1769.         q = 0;
  1770.         if (sign == -1) {
  1771.             outputbuffer[q++] = '-';
  1772.         }

  1773.         if (p != rawdigits.length) {
  1774.             // there are non zero digits...
  1775.             outputbuffer[q++] = rawdigits[p++];
  1776.             outputbuffer[q++] = '.';

  1777.             while (p < rawdigits.length) {
  1778.                 outputbuffer[q++] = rawdigits[p++];
  1779.             }
  1780.         } else {
  1781.             outputbuffer[q++] = '0';
  1782.             outputbuffer[q++] = '.';
  1783.             outputbuffer[q++] = '0';
  1784.             outputbuffer[q++] = 'e';
  1785.             outputbuffer[q++] = '0';
  1786.             return String.valueOf(outputbuffer, 0, 5);
  1787.         }

  1788.         outputbuffer[q++] = 'e';

  1789.         // Find the msd of the exponent

  1790.         e = exp * 4 - shf - 1;
  1791.         ae = e;
  1792.         if (e < 0) {
  1793.             ae = -e;
  1794.         }

  1795.         // Find the largest p such that p < e
  1796.         p = 1000000000;
  1797.         while (p > ae) {
  1798.             p /= 10;
  1799.         }

  1800.         if (e < 0) {
  1801.             outputbuffer[q++] = '-';
  1802.         }

  1803.         while (p > 0) {
  1804.             outputbuffer[q++] = (char)(ae / p + '0');
  1805.             ae %= p;
  1806.             p /= 10;
  1807.         }

  1808.         return String.valueOf(outputbuffer, 0, q);
  1809.     }

  1810.     /** Convert an instance to a string using normal notation.
  1811.      * @return string representation of the instance in normal notation
  1812.      */
  1813.     protected String dfp2string() {
  1814.         char[] buffer = new char[mant.length * 4 + 20];
  1815.         int p = 1;
  1816.         int q;
  1817.         int e = exp;
  1818.         boolean pointInserted = false;

  1819.         buffer[0] = ' ';

  1820.         if (e <= 0) {
  1821.             buffer[p++] = '0';
  1822.             buffer[p++] = '.';
  1823.             pointInserted = true;
  1824.         }

  1825.         while (e < 0) {
  1826.             buffer[p++] = '0';
  1827.             buffer[p++] = '0';
  1828.             buffer[p++] = '0';
  1829.             buffer[p++] = '0';
  1830.             e++;
  1831.         }

  1832.         for (int i = mant.length - 1; i >= 0; i--) {
  1833.             buffer[p++] = (char) ((mant[i] / 1000) + '0');
  1834.             buffer[p++] = (char) (((mant[i] / 100) % 10) + '0');
  1835.             buffer[p++] = (char) (((mant[i] / 10) % 10) + '0');
  1836.             buffer[p++] = (char) (((mant[i]) % 10) + '0');
  1837.             if (--e == 0) {
  1838.                 buffer[p++] = '.';
  1839.                 pointInserted = true;
  1840.             }
  1841.         }

  1842.         while (e > 0) {
  1843.             buffer[p++] = '0';
  1844.             buffer[p++] = '0';
  1845.             buffer[p++] = '0';
  1846.             buffer[p++] = '0';
  1847.             e--;
  1848.         }

  1849.         if (!pointInserted) {
  1850.             // Ensure we have a radix point!
  1851.             buffer[p++] = '.';
  1852.         }

  1853.         // Suppress leading zeros
  1854.         q = 1;
  1855.         while (buffer[q] == '0') {
  1856.             q++;
  1857.         }
  1858.         if (buffer[q] == '.') {
  1859.             q--;
  1860.         }

  1861.         // Suppress trailing zeros
  1862.         while (buffer[p - 1] == '0') {
  1863.             p--;
  1864.         }

  1865.         // Insert sign
  1866.         if (sign < 0) {
  1867.             buffer[--q] = '-';
  1868.         }

  1869.         return String.valueOf(buffer, q, p - q);
  1870.     }

  1871.     /** Raises a trap.  This does not set the corresponding flag however.
  1872.      *  @param type the trap type
  1873.      *  @param what - name of routine trap occurred in
  1874.      *  @param oper - input operator to function
  1875.      *  @param result - the result computed prior to the trap
  1876.      *  @return The suggested return value from the trap handler
  1877.      */
  1878.     public Dfp dotrap(int type, String what, Dfp oper, Dfp result) {
  1879.         Dfp def = result;

  1880.         switch (type) {
  1881.         case DfpField.FLAG_INVALID:
  1882.             def = newInstance(getZero());
  1883.             def.sign = result.sign;
  1884.             def.nans = QNAN;
  1885.             break;

  1886.         case DfpField.FLAG_DIV_ZERO:
  1887.             if (nans == FINITE && mant[mant.length - 1] != 0) {
  1888.                 // normal case, we are finite, non-zero
  1889.                 def = newInstance(getZero());
  1890.                 def.sign = (byte) (sign * oper.sign);
  1891.                 def.nans = INFINITE;
  1892.             }

  1893.             if (nans == FINITE && mant[mant.length - 1] == 0) {
  1894.                 // 0/0
  1895.                 def = newInstance(getZero());
  1896.                 def.nans = QNAN;
  1897.             }

  1898.             if (nans == INFINITE || nans == QNAN) {
  1899.                 def = newInstance(getZero());
  1900.                 def.nans = QNAN;
  1901.             }

  1902.             if (nans == INFINITE || nans == SNAN) {
  1903.                 def = newInstance(getZero());
  1904.                 def.nans = QNAN;
  1905.             }
  1906.             break;

  1907.         case DfpField.FLAG_UNDERFLOW:
  1908.             if ((result.exp + mant.length) < MIN_EXP) {
  1909.                 def = newInstance(getZero());
  1910.                 def.sign = result.sign;
  1911.             } else {
  1912.                 def = newInstance(result);  // gradual underflow
  1913.             }
  1914.             result.exp += ERR_SCALE;
  1915.             break;

  1916.         case DfpField.FLAG_OVERFLOW:
  1917.             result.exp -= ERR_SCALE;
  1918.             def = newInstance(getZero());
  1919.             def.sign = result.sign;
  1920.             def.nans = INFINITE;
  1921.             break;

  1922.         default: def = result; break;
  1923.         }

  1924.         return trap(type, what, oper, def, result);
  1925.     }

  1926.     /** Trap handler.  Subclasses may override this to provide trap
  1927.      *  functionality per IEEE 854-1987.
  1928.      *
  1929.      *  @param type  The exception type - e.g. FLAG_OVERFLOW
  1930.      *  @param what  The name of the routine we were in e.g. divide()
  1931.      *  @param oper  An operand to this function if any
  1932.      *  @param def   The default return value if trap not enabled
  1933.      *  @param result    The result that is specified to be delivered per
  1934.      *                   IEEE 854, if any
  1935.      *  @return the value that should be return by the operation triggering the trap
  1936.      */
  1937.     protected Dfp trap(int type, String what, Dfp oper, Dfp def, Dfp result) {
  1938.         return def;
  1939.     }

  1940.     /** Returns the type - one of FINITE, INFINITE, SNAN, QNAN.
  1941.      * @return type of the number
  1942.      */
  1943.     public int classify() {
  1944.         return nans;
  1945.     }

  1946.     /** Creates an instance that is the same as x except that it has the sign of y.
  1947.      * abs(x) = dfp.copysign(x, dfp.one)
  1948.      * @param x number to get the value from
  1949.      * @param y number to get the sign from
  1950.      * @return a number with the value of x and the sign of y
  1951.      */
  1952.     public static Dfp copySign(final Dfp x, final Dfp y) {
  1953.         Dfp result = x.newInstance(x);
  1954.         result.sign = y.sign;
  1955.         return result;
  1956.     }

  1957.     /** Returns the next number greater than this one in the direction of x.
  1958.      * If this==x then simply returns this.
  1959.      * @param x direction where to look at
  1960.      * @return closest number next to instance in the direction of x
  1961.      */
  1962.     public Dfp nextAfter(final Dfp x) {

  1963.         // make sure we don't mix number with different precision
  1964.         if (field.getRadixDigits() != x.field.getRadixDigits()) {
  1965.             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
  1966.             final Dfp result = newInstance(getZero());
  1967.             result.nans = QNAN;
  1968.             return dotrap(DfpField.FLAG_INVALID, NEXT_AFTER_TRAP, x, result);
  1969.         }

  1970.         // if this is greater than x
  1971.         boolean up = this.lessThan(x);

  1972.         if (compare(this, x) == 0) {
  1973.             return newInstance(x);
  1974.         }

  1975.         if (lessThan(getZero())) {
  1976.             up = !up;
  1977.         }

  1978.         final Dfp inc;
  1979.         Dfp result;
  1980.         if (up) {
  1981.             inc = newInstance(getOne());
  1982.             inc.exp = this.exp - mant.length + 1;
  1983.             inc.sign = this.sign;

  1984.             if (this.equals(getZero())) {
  1985.                 inc.exp = MIN_EXP - mant.length;
  1986.             }

  1987.             result = add(inc);
  1988.         } else {
  1989.             inc = newInstance(getOne());
  1990.             inc.exp = this.exp;
  1991.             inc.sign = this.sign;

  1992.             if (this.equals(inc)) {
  1993.                 inc.exp = this.exp - mant.length;
  1994.             } else {
  1995.                 inc.exp = this.exp - mant.length + 1;
  1996.             }

  1997.             if (this.equals(getZero())) {
  1998.                 inc.exp = MIN_EXP - mant.length;
  1999.             }

  2000.             result = this.subtract(inc);
  2001.         }

  2002.         if (result.classify() == INFINITE && this.classify() != INFINITE) {
  2003.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  2004.             result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result);
  2005.         }

  2006.         if (result.equals(getZero()) && !this.equals(getZero())) {
  2007.             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
  2008.             result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result);
  2009.         }

  2010.         return result;
  2011.     }

  2012.     /** Convert the instance into a double.
  2013.      * @return a double approximating the instance
  2014.      * @see #toSplitDouble()
  2015.      */
  2016.     public double toDouble() {

  2017.         if (isInfinite()) {
  2018.             if (lessThan(getZero())) {
  2019.                 return Double.NEGATIVE_INFINITY;
  2020.             } else {
  2021.                 return Double.POSITIVE_INFINITY;
  2022.             }
  2023.         }

  2024.         if (isNaN()) {
  2025.             return Double.NaN;
  2026.         }

  2027.         Dfp y = this;
  2028.         boolean negate = false;
  2029.         int cmp0 = compare(this, getZero());
  2030.         if (cmp0 == 0) {
  2031.             return sign < 0 ? -0.0 : +0.0;
  2032.         } else if (cmp0 < 0) {
  2033.             y = negate();
  2034.             negate = true;
  2035.         }

  2036.         /* Find the exponent, first estimate by integer log10, then adjust.
  2037.          Should be faster than doing a natural logarithm.  */
  2038.         int exponent = (int)(y.intLog10() * 3.32);
  2039.         if (exponent < 0) {
  2040.             exponent--;
  2041.         }

  2042.         Dfp tempDfp = DfpMath.pow(getTwo(), exponent);
  2043.         while (tempDfp.lessThan(y) || tempDfp.equals(y)) {
  2044.             tempDfp = tempDfp.multiply(2);
  2045.             exponent++;
  2046.         }
  2047.         exponent--;

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

  2049.         y = y.divide(DfpMath.pow(getTwo(), exponent));
  2050.         if (exponent > -1023) {
  2051.             y = y.subtract(getOne());
  2052.         }

  2053.         if (exponent < -1074) {
  2054.             return 0;
  2055.         }

  2056.         if (exponent > 1023) {
  2057.             return negate ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
  2058.         }


  2059.         y = y.multiply(newInstance(4503599627370496L)).rint();
  2060.         String str = y.toString();
  2061.         str = str.substring(0, str.length() - 1);
  2062.         long mantissa = Long.parseLong(str);

  2063.         if (mantissa == 4503599627370496L) {
  2064.             // Handle special case where we round up to next power of two
  2065.             mantissa = 0;
  2066.             exponent++;
  2067.         }

  2068.         /* Its going to be subnormal, so make adjustments */
  2069.         if (exponent <= -1023) {
  2070.             exponent--;
  2071.         }

  2072.         while (exponent < -1023) {
  2073.             exponent++;
  2074.             mantissa >>>= 1;
  2075.         }

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

  2078.         if (negate) {
  2079.             x = -x;
  2080.         }

  2081.         return x;
  2082.     }

  2083.     /** Convert the instance into a split double.
  2084.      * @return an array of two doubles which sum represent the instance
  2085.      * @see #toDouble()
  2086.      */
  2087.     public double[] toSplitDouble() {
  2088.         double[] split = new double[2];
  2089.         long mask = 0xffffffffc0000000L;

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

  2092.         return split;
  2093.     }

  2094.     /** {@inheritDoc}
  2095.      * @since 3.2
  2096.      */
  2097.     @Override
  2098.     public double getReal() {
  2099.         return toDouble();
  2100.     }

  2101.     /** {@inheritDoc}
  2102.      * @since 3.2
  2103.      */
  2104.     @Override
  2105.     public Dfp add(final double a) {
  2106.         return add(newInstance(a));
  2107.     }

  2108.     /** {@inheritDoc}
  2109.      * @since 3.2
  2110.      */
  2111.     @Override
  2112.     public Dfp subtract(final double a) {
  2113.         return subtract(newInstance(a));
  2114.     }

  2115.     /** {@inheritDoc}
  2116.      * @since 3.2
  2117.      */
  2118.     @Override
  2119.     public Dfp multiply(final double a) {
  2120.         return multiply(newInstance(a));
  2121.     }

  2122.     /** {@inheritDoc}
  2123.      * @since 3.2
  2124.      */
  2125.     @Override
  2126.     public Dfp divide(final double a) {
  2127.         return divide(newInstance(a));
  2128.     }

  2129.     /** {@inheritDoc}
  2130.      * @since 3.2
  2131.      */
  2132.     @Override
  2133.     public Dfp remainder(final double a) {
  2134.         return remainder(newInstance(a));
  2135.     }

  2136.     /** {@inheritDoc}
  2137.      * @since 3.2
  2138.      */
  2139.     @Override
  2140.     public long round() {
  2141.         return Math.round(toDouble());
  2142.     }

  2143.     /** {@inheritDoc}
  2144.      * @since 3.2
  2145.      */
  2146.     @Override
  2147.     public Dfp signum() {
  2148.         if (isNaN() || isZero()) {
  2149.             return this;
  2150.         } else {
  2151.             return newInstance(sign > 0 ? +1 : -1);
  2152.         }
  2153.     }

  2154.     /** {@inheritDoc}
  2155.      * @since 3.2
  2156.      */
  2157.     @Override
  2158.     public Dfp copySign(final Dfp s) {
  2159.         if ((sign >= 0 && s.sign >= 0) || (sign < 0 && s.sign < 0)) { // Sign is currently OK
  2160.             return this;
  2161.         }
  2162.         return negate(); // flip sign
  2163.     }

  2164.     /** {@inheritDoc}
  2165.      * @since 3.2
  2166.      */
  2167.     @Override
  2168.     public Dfp copySign(final double s) {
  2169.         long sb = Double.doubleToLongBits(s);
  2170.         if ((sign >= 0 && sb >= 0) || (sign < 0 && sb < 0)) { // Sign is currently OK
  2171.             return this;
  2172.         }
  2173.         return negate(); // flip sign
  2174.     }

  2175.     /** {@inheritDoc}
  2176.      * @since 3.2
  2177.      */
  2178.     @Override
  2179.     public Dfp scalb(final int n) {
  2180.         return multiply(DfpMath.pow(getTwo(), n));
  2181.     }

  2182.     /** {@inheritDoc}
  2183.      * @since 3.2
  2184.      */
  2185.     @Override
  2186.     public Dfp hypot(final Dfp y) {
  2187.         return multiply(this).add(y.multiply(y)).sqrt();
  2188.     }

  2189.     /** {@inheritDoc}
  2190.      * @since 3.2
  2191.      */
  2192.     @Override
  2193.     public Dfp cbrt() {
  2194.         return rootN(3);
  2195.     }

  2196.     /** {@inheritDoc}
  2197.      * @since 3.2
  2198.      */
  2199.     @Override
  2200.     public Dfp rootN(final int n) {
  2201.         return (sign >= 0) ?
  2202.                DfpMath.pow(this, getOne().divide(n)) :
  2203.                DfpMath.pow(negate(), getOne().divide(n)).negate();
  2204.     }

  2205.     /** {@inheritDoc}
  2206.      * @since 3.2
  2207.      */
  2208.     @Override
  2209.     public Dfp pow(final double p) {
  2210.         return DfpMath.pow(this, newInstance(p));
  2211.     }

  2212.     /** {@inheritDoc}
  2213.      * @since 3.2
  2214.      */
  2215.     @Override
  2216.     public Dfp pow(final int n) {
  2217.         return DfpMath.pow(this, n);
  2218.     }

  2219.     /** {@inheritDoc}
  2220.      * @since 3.2
  2221.      */
  2222.     @Override
  2223.     public Dfp pow(final Dfp e) {
  2224.         return DfpMath.pow(this, e);
  2225.     }

  2226.     /** {@inheritDoc}
  2227.      * @since 3.2
  2228.      */
  2229.     @Override
  2230.     public Dfp exp() {
  2231.         return DfpMath.exp(this);
  2232.     }

  2233.     /** {@inheritDoc}
  2234.      * @since 3.2
  2235.      */
  2236.     @Override
  2237.     public Dfp expm1() {
  2238.         return DfpMath.exp(this).subtract(getOne());
  2239.     }

  2240.     /** {@inheritDoc}
  2241.      * @since 3.2
  2242.      */
  2243.     @Override
  2244.     public Dfp log() {
  2245.         return DfpMath.log(this);
  2246.     }

  2247.     /** {@inheritDoc}
  2248.      * @since 3.2
  2249.      */
  2250.     @Override
  2251.     public Dfp log1p() {
  2252.         return DfpMath.log(this.add(getOne()));
  2253.     }

  2254.     /** {@inheritDoc}
  2255.      * @since 3.2, return type changed to {@link Dfp} in 4.0
  2256.      */
  2257.     @Override
  2258.     public Dfp log10() {
  2259.         return DfpMath.log(this).divide(DfpMath.log(newInstance(10)));
  2260.     }

  2261.     /** {@inheritDoc}
  2262.      * @since 3.2
  2263.      */
  2264.     @Override
  2265.     public Dfp cos() {
  2266.         return DfpMath.cos(this);
  2267.     }

  2268.     /** {@inheritDoc}
  2269.      * @since 3.2
  2270.      */
  2271.     @Override
  2272.     public Dfp sin() {
  2273.         return DfpMath.sin(this);
  2274.     }

  2275.     /** {@inheritDoc}
  2276.      * @since 3.2
  2277.      */
  2278.     @Override
  2279.     public Dfp tan() {
  2280.         return DfpMath.tan(this);
  2281.     }

  2282.     /** {@inheritDoc}
  2283.      * @since 3.2
  2284.      */
  2285.     @Override
  2286.     public Dfp acos() {
  2287.         return DfpMath.acos(this);
  2288.     }

  2289.     /** {@inheritDoc}
  2290.      * @since 3.2
  2291.      */
  2292.     @Override
  2293.     public Dfp asin() {
  2294.         return DfpMath.asin(this);
  2295.     }

  2296.     /** {@inheritDoc}
  2297.      * @since 3.2
  2298.      */
  2299.     @Override
  2300.     public Dfp atan() {
  2301.         return DfpMath.atan(this);
  2302.     }

  2303.     /** {@inheritDoc}
  2304.      * @since 3.2
  2305.      */
  2306.     @Override
  2307.     public Dfp atan2(final Dfp x)
  2308.         throws DimensionMismatchException {

  2309.         // compute r = sqrt(x^2+y^2)
  2310.         final Dfp r = x.multiply(x).add(multiply(this)).sqrt();

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

  2312.             // compute atan2(y, x) = 2 atan(y / (r + x))
  2313.             return getTwo().multiply(divide(r.add(x)).atan());
  2314.         } else {

  2315.             // compute atan2(y, x) = +/- pi - 2 atan(y / (r - x))
  2316.             final Dfp tmp = getTwo().multiply(divide(r.subtract(x)).atan());
  2317.             final Dfp pmPi = newInstance((tmp.sign <= 0) ? -Math.PI : Math.PI);
  2318.             return pmPi.subtract(tmp);
  2319.         }
  2320.     }

  2321.     /** {@inheritDoc}
  2322.      * @since 3.2
  2323.      */
  2324.     @Override
  2325.     public Dfp cosh() {
  2326.         return DfpMath.exp(this).add(DfpMath.exp(negate())).divide(2);
  2327.     }

  2328.     /** {@inheritDoc}
  2329.      * @since 3.2
  2330.      */
  2331.     @Override
  2332.     public Dfp sinh() {
  2333.         return DfpMath.exp(this).subtract(DfpMath.exp(negate())).divide(2);
  2334.     }

  2335.     /** {@inheritDoc}
  2336.      * @since 3.2
  2337.      */
  2338.     @Override
  2339.     public Dfp tanh() {
  2340.         final Dfp ePlus  = DfpMath.exp(this);
  2341.         final Dfp eMinus = DfpMath.exp(negate());
  2342.         return ePlus.subtract(eMinus).divide(ePlus.add(eMinus));
  2343.     }

  2344.     /** {@inheritDoc}
  2345.      * @since 3.2
  2346.      */
  2347.     @Override
  2348.     public Dfp acosh() {
  2349.         return multiply(this).subtract(getOne()).sqrt().add(this).log();
  2350.     }

  2351.     /** {@inheritDoc}
  2352.      * @since 3.2
  2353.      */
  2354.     @Override
  2355.     public Dfp asinh() {
  2356.         return multiply(this).add(getOne()).sqrt().add(this).log();
  2357.     }

  2358.     /** {@inheritDoc}
  2359.      * @since 3.2
  2360.      */
  2361.     @Override
  2362.     public Dfp atanh() {
  2363.         return getOne().add(this).divide(getOne().subtract(this)).log().divide(2);
  2364.     }

  2365.     /** {@inheritDoc}
  2366.      * @since 3.2
  2367.      */
  2368.     @Override
  2369.     public Dfp linearCombination(final Dfp[] a, final Dfp[] b)
  2370.         throws DimensionMismatchException {
  2371.         if (a.length != b.length) {
  2372.             throw new DimensionMismatchException(a.length, b.length);
  2373.         }
  2374.         Dfp r = getZero();
  2375.         for (int i = 0; i < a.length; ++i) {
  2376.             r = r.add(a[i].multiply(b[i]));
  2377.         }
  2378.         return r;
  2379.     }

  2380.     /** {@inheritDoc}
  2381.      * @since 3.2
  2382.      */
  2383.     @Override
  2384.     public Dfp linearCombination(final double[] a, final Dfp[] b)
  2385.         throws DimensionMismatchException {
  2386.         if (a.length != b.length) {
  2387.             throw new DimensionMismatchException(a.length, b.length);
  2388.         }
  2389.         Dfp r = getZero();
  2390.         for (int i = 0; i < a.length; ++i) {
  2391.             r = r.add(b[i].multiply(a[i]));
  2392.         }
  2393.         return r;
  2394.     }

  2395.     /** {@inheritDoc}
  2396.      * @since 3.2
  2397.      */
  2398.     @Override
  2399.     public Dfp linearCombination(final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2) {
  2400.         return a1.multiply(b1).add(a2.multiply(b2));
  2401.     }

  2402.     /** {@inheritDoc}
  2403.      * @since 3.2
  2404.      */
  2405.     @Override
  2406.     public Dfp linearCombination(final double a1, final Dfp b1, final double a2, final Dfp b2) {
  2407.         return b1.multiply(a1).add(b2.multiply(a2));
  2408.     }

  2409.     /** {@inheritDoc}
  2410.      * @since 3.2
  2411.      */
  2412.     @Override
  2413.     public Dfp linearCombination(final Dfp a1, final Dfp b1,
  2414.                                  final Dfp a2, final Dfp b2,
  2415.                                  final Dfp a3, final Dfp b3) {
  2416.         return a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3));
  2417.     }

  2418.     /** {@inheritDoc}
  2419.      * @since 3.2
  2420.      */
  2421.     @Override
  2422.     public Dfp linearCombination(final double a1, final Dfp b1,
  2423.                                  final double a2, final Dfp b2,
  2424.                                  final double a3, final Dfp b3) {
  2425.         return b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3));
  2426.     }

  2427.     /** {@inheritDoc}
  2428.      * @since 3.2
  2429.      */
  2430.     @Override
  2431.     public Dfp linearCombination(final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2,
  2432.                                  final Dfp a3, final Dfp b3, final Dfp a4, final Dfp b4) {
  2433.         return a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3)).add(a4.multiply(b4));
  2434.     }

  2435.     /** {@inheritDoc}
  2436.      * @since 3.2
  2437.      */
  2438.     @Override
  2439.     public Dfp linearCombination(final double a1, final Dfp b1, final double a2, final Dfp b2,
  2440.                                  final double a3, final Dfp b3, final double a4, final Dfp b4) {
  2441.         return b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3)).add(b4.multiply(a4));
  2442.     }
  2443. }