xref: /aosp_15_r20/external/apache-commons-math/src/main/java/org/apache/commons/math3/dfp/Dfp.java (revision d3fac44428dd0296a04a50c6827e3205b8dbea8a)
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 
18 package org.apache.commons.math3.dfp;
19 
20 import org.apache.commons.math3.RealFieldElement;
21 import org.apache.commons.math3.exception.DimensionMismatchException;
22 import org.apache.commons.math3.util.FastMath;
23 
24 import java.util.Arrays;
25 
26 /**
27  * Decimal floating point library for Java
28  *
29  * <p>Another floating point class. This one is built using radix 10000 which is 10<sup>4</sup>, so
30  * its almost decimal.
31  *
32  * <p>The design goals here are:
33  *
34  * <ol>
35  *   <li>Decimal math, or close to it
36  *   <li>Settable precision (but no mix between numbers using different settings)
37  *   <li>Portability. Code should be kept as portable as possible.
38  *   <li>Performance
39  *   <li>Accuracy - Results should always be +/- 1 ULP for basic algebraic operation
40  *   <li>Comply with IEEE 854-1987 as much as possible. (See IEEE 854-1987 notes below)
41  * </ol>
42  *
43  * <p>Trade offs:
44  *
45  * <ol>
46  *   <li>Memory foot print. I'm using more memory than necessary to represent numbers to get better
47  *       performance.
48  *   <li>Digits are bigger, so rounding is a greater loss. So, if you really need 12 decimal digits,
49  *       better use 4 base 10000 digits there can be one partially filled.
50  * </ol>
51  *
52  * <p>Numbers are represented in the following form:
53  *
54  * <pre>
55  *  n  =  sign &times; mant &times; (radix)<sup>exp</sup>;</p>
56  *  </pre>
57  *
58  * where sign is &plusmn;1, mantissa represents a fractional number between zero and one. mant[0] is
59  * the least significant digit. exp is in the range of -32767 to 32768
60  *
61  * <p>IEEE 854-1987 Notes and differences
62  *
63  * <p>IEEE 854 requires the radix to be either 2 or 10. The radix here is 10000, so that requirement
64  * is not met, but it is possible that a subclassed can be made to make it behave as a radix 10
65  * number. It is my opinion that if it looks and behaves as a radix 10 number then it is one and
66  * that requirement would be met.
67  *
68  * <p>The radix of 10000 was chosen because it should be faster to operate on 4 decimal digits at
69  * once instead of one at a time. Radix 10 behavior can be realized by adding an additional rounding
70  * step to ensure that the number of decimal digits represented is constant.
71  *
72  * <p>The IEEE standard specifically leaves out internal data encoding, so it is reasonable to
73  * conclude that such a subclass of this radix 10000 system is merely an encoding of a radix 10
74  * system.
75  *
76  * <p>IEEE 854 also specifies the existence of "sub-normal" numbers. This class does not contain any
77  * such entities. The most significant radix 10000 digit is always non-zero. Instead, we support
78  * "gradual underflow" by raising the underflow flag for numbers less with exponent less than
79  * expMin, but don't flush to zero until the exponent reaches MIN_EXP-digits. Thus the smallest
80  * number we can represent would be: 1E(-(MIN_EXP-digits-1)*4), eg, for digits=5, MIN_EXP=-32767,
81  * that would be 1e-131092.
82  *
83  * <p>IEEE 854 defines that the implied radix point lies just to the right of the most significant
84  * digit and to the left of the remaining digits. This implementation puts the implied radix point
85  * to the left of all digits including the most significant one. The most significant digit here is
86  * the one just to the right of the radix point. This is a fine detail and is really only a matter
87  * of definition. Any side effects of this can be rendered invisible by a subclass.
88  *
89  * @see DfpField
90  * @since 2.2
91  */
92 public class Dfp implements RealFieldElement<Dfp> {
93 
94     /** The radix, or base of this system. Set to 10000 */
95     public static final int RADIX = 10000;
96 
97     /** The minimum exponent before underflow is signaled. Flush to zero occurs at minExp-DIGITS */
98     public static final int MIN_EXP = -32767;
99 
100     /** The maximum exponent before overflow is signaled and results flushed to infinity */
101     public static final int MAX_EXP = 32768;
102 
103     /** The amount under/overflows are scaled by before going to trap handler */
104     public static final int ERR_SCALE = 32760;
105 
106     /** Indicator value for normal finite numbers. */
107     public static final byte FINITE = 0;
108 
109     /** Indicator value for Infinity. */
110     public static final byte INFINITE = 1;
111 
112     /** Indicator value for signaling NaN. */
113     public static final byte SNAN = 2;
114 
115     /** Indicator value for quiet NaN. */
116     public static final byte QNAN = 3;
117 
118     /** String for NaN representation. */
119     private static final String NAN_STRING = "NaN";
120 
121     /** String for positive infinity representation. */
122     private static final String POS_INFINITY_STRING = "Infinity";
123 
124     /** String for negative infinity representation. */
125     private static final String NEG_INFINITY_STRING = "-Infinity";
126 
127     /** Name for traps triggered by addition. */
128     private static final String ADD_TRAP = "add";
129 
130     /** Name for traps triggered by multiplication. */
131     private static final String MULTIPLY_TRAP = "multiply";
132 
133     /** Name for traps triggered by division. */
134     private static final String DIVIDE_TRAP = "divide";
135 
136     /** Name for traps triggered by square root. */
137     private static final String SQRT_TRAP = "sqrt";
138 
139     /** Name for traps triggered by alignment. */
140     private static final String ALIGN_TRAP = "align";
141 
142     /** Name for traps triggered by truncation. */
143     private static final String TRUNC_TRAP = "trunc";
144 
145     /** Name for traps triggered by nextAfter. */
146     private static final String NEXT_AFTER_TRAP = "nextAfter";
147 
148     /** Name for traps triggered by lessThan. */
149     private static final String LESS_THAN_TRAP = "lessThan";
150 
151     /** Name for traps triggered by greaterThan. */
152     private static final String GREATER_THAN_TRAP = "greaterThan";
153 
154     /** Name for traps triggered by newInstance. */
155     private static final String NEW_INSTANCE_TRAP = "newInstance";
156 
157     /** Mantissa. */
158     protected int[] mant;
159 
160     /** Sign bit: 1 for positive, -1 for negative. */
161     protected byte sign;
162 
163     /** Exponent. */
164     protected int exp;
165 
166     /** Indicator for non-finite / non-number values. */
167     protected byte nans;
168 
169     /** Factory building similar Dfp's. */
170     private final DfpField field;
171 
172     /**
173      * Makes an instance with a value of zero.
174      *
175      * @param field field to which this instance belongs
176      */
Dfp(final DfpField field)177     protected Dfp(final DfpField field) {
178         mant = new int[field.getRadixDigits()];
179         sign = 1;
180         exp = 0;
181         nans = FINITE;
182         this.field = field;
183     }
184 
185     /**
186      * Create an instance from a byte value.
187      *
188      * @param field field to which this instance belongs
189      * @param x value to convert to an instance
190      */
Dfp(final DfpField field, byte x)191     protected Dfp(final DfpField field, byte x) {
192         this(field, (long) x);
193     }
194 
195     /**
196      * Create an instance from an int value.
197      *
198      * @param field field to which this instance belongs
199      * @param x value to convert to an instance
200      */
Dfp(final DfpField field, int x)201     protected Dfp(final DfpField field, int x) {
202         this(field, (long) x);
203     }
204 
205     /**
206      * Create an instance from a long value.
207      *
208      * @param field field to which this instance belongs
209      * @param x value to convert to an instance
210      */
Dfp(final DfpField field, long x)211     protected Dfp(final DfpField field, long x) {
212 
213         // initialize as if 0
214         mant = new int[field.getRadixDigits()];
215         nans = FINITE;
216         this.field = field;
217 
218         boolean isLongMin = false;
219         if (x == Long.MIN_VALUE) {
220             // special case for Long.MIN_VALUE (-9223372036854775808)
221             // we must shift it before taking its absolute value
222             isLongMin = true;
223             ++x;
224         }
225 
226         // set the sign
227         if (x < 0) {
228             sign = -1;
229             x = -x;
230         } else {
231             sign = 1;
232         }
233 
234         exp = 0;
235         while (x != 0) {
236             System.arraycopy(mant, mant.length - exp, mant, mant.length - 1 - exp, exp);
237             mant[mant.length - 1] = (int) (x % RADIX);
238             x /= RADIX;
239             exp++;
240         }
241 
242         if (isLongMin) {
243             // remove the shift added for Long.MIN_VALUE
244             // we know in this case that fixing the last digit is sufficient
245             for (int i = 0; i < mant.length - 1; i++) {
246                 if (mant[i] != 0) {
247                     mant[i]++;
248                     break;
249                 }
250             }
251         }
252     }
253 
254     /**
255      * Create an instance from a double value.
256      *
257      * @param field field to which this instance belongs
258      * @param x value to convert to an instance
259      */
Dfp(final DfpField field, double x)260     protected Dfp(final DfpField field, double x) {
261 
262         // initialize as if 0
263         mant = new int[field.getRadixDigits()];
264         sign = 1;
265         exp = 0;
266         nans = FINITE;
267         this.field = field;
268 
269         long bits = Double.doubleToLongBits(x);
270         long mantissa = bits & 0x000fffffffffffffL;
271         int exponent = (int) ((bits & 0x7ff0000000000000L) >> 52) - 1023;
272 
273         if (exponent == -1023) {
274             // Zero or sub-normal
275             if (x == 0) {
276                 // make sure 0 has the right sign
277                 if ((bits & 0x8000000000000000L) != 0) {
278                     sign = -1;
279                 }
280                 return;
281             }
282 
283             exponent++;
284 
285             // Normalize the subnormal number
286             while ((mantissa & 0x0010000000000000L) == 0) {
287                 exponent--;
288                 mantissa <<= 1;
289             }
290             mantissa &= 0x000fffffffffffffL;
291         }
292 
293         if (exponent == 1024) {
294             // infinity or NAN
295             if (x != x) {
296                 sign = (byte) 1;
297                 nans = QNAN;
298             } else if (x < 0) {
299                 sign = (byte) -1;
300                 nans = INFINITE;
301             } else {
302                 sign = (byte) 1;
303                 nans = INFINITE;
304             }
305             return;
306         }
307 
308         Dfp xdfp = new Dfp(field, mantissa);
309         xdfp =
310                 xdfp.divide(new Dfp(field, 4503599627370496l))
311                         .add(field.getOne()); // Divide by 2^52, then add one
312         xdfp = xdfp.multiply(DfpMath.pow(field.getTwo(), exponent));
313 
314         if ((bits & 0x8000000000000000L) != 0) {
315             xdfp = xdfp.negate();
316         }
317 
318         System.arraycopy(xdfp.mant, 0, mant, 0, mant.length);
319         sign = xdfp.sign;
320         exp = xdfp.exp;
321         nans = xdfp.nans;
322     }
323 
324     /**
325      * Copy constructor.
326      *
327      * @param d instance to copy
328      */
Dfp(final Dfp d)329     public Dfp(final Dfp d) {
330         mant = d.mant.clone();
331         sign = d.sign;
332         exp = d.exp;
333         nans = d.nans;
334         field = d.field;
335     }
336 
337     /**
338      * Create an instance from a String representation.
339      *
340      * @param field field to which this instance belongs
341      * @param s string representation of the instance
342      */
Dfp(final DfpField field, final String s)343     protected Dfp(final DfpField field, final String s) {
344 
345         // initialize as if 0
346         mant = new int[field.getRadixDigits()];
347         sign = 1;
348         exp = 0;
349         nans = FINITE;
350         this.field = field;
351 
352         boolean decimalFound = false;
353         final int rsize = 4; // size of radix in decimal digits
354         final int offset = 4; // Starting offset into Striped
355         final char[] striped = new char[getRadixDigits() * rsize + offset * 2];
356 
357         // Check some special cases
358         if (s.equals(POS_INFINITY_STRING)) {
359             sign = (byte) 1;
360             nans = INFINITE;
361             return;
362         }
363 
364         if (s.equals(NEG_INFINITY_STRING)) {
365             sign = (byte) -1;
366             nans = INFINITE;
367             return;
368         }
369 
370         if (s.equals(NAN_STRING)) {
371             sign = (byte) 1;
372             nans = QNAN;
373             return;
374         }
375 
376         // Check for scientific notation
377         int p = s.indexOf("e");
378         if (p == -1) { // try upper case?
379             p = s.indexOf("E");
380         }
381 
382         final String fpdecimal;
383         int sciexp = 0;
384         if (p != -1) {
385             // scientific notation
386             fpdecimal = s.substring(0, p);
387             String fpexp = s.substring(p + 1);
388             boolean negative = false;
389 
390             for (int i = 0; i < fpexp.length(); i++) {
391                 if (fpexp.charAt(i) == '-') {
392                     negative = true;
393                     continue;
394                 }
395                 if (fpexp.charAt(i) >= '0' && fpexp.charAt(i) <= '9') {
396                     sciexp = sciexp * 10 + fpexp.charAt(i) - '0';
397                 }
398             }
399 
400             if (negative) {
401                 sciexp = -sciexp;
402             }
403         } else {
404             // normal case
405             fpdecimal = s;
406         }
407 
408         // If there is a minus sign in the number then it is negative
409         if (fpdecimal.indexOf("-") != -1) {
410             sign = -1;
411         }
412 
413         // First off, find all of the leading zeros, trailing zeros, and significant digits
414         p = 0;
415 
416         // Move p to first significant digit
417         int decimalPos = 0;
418         for (; ; ) {
419             if (fpdecimal.charAt(p) >= '1' && fpdecimal.charAt(p) <= '9') {
420                 break;
421             }
422 
423             if (decimalFound && fpdecimal.charAt(p) == '0') {
424                 decimalPos--;
425             }
426 
427             if (fpdecimal.charAt(p) == '.') {
428                 decimalFound = true;
429             }
430 
431             p++;
432 
433             if (p == fpdecimal.length()) {
434                 break;
435             }
436         }
437 
438         // Copy the string onto Stripped
439         int q = offset;
440         striped[0] = '0';
441         striped[1] = '0';
442         striped[2] = '0';
443         striped[3] = '0';
444         int significantDigits = 0;
445         for (; ; ) {
446             if (p == (fpdecimal.length())) {
447                 break;
448             }
449 
450             // Don't want to run pass the end of the array
451             if (q == mant.length * rsize + offset + 1) {
452                 break;
453             }
454 
455             if (fpdecimal.charAt(p) == '.') {
456                 decimalFound = true;
457                 decimalPos = significantDigits;
458                 p++;
459                 continue;
460             }
461 
462             if (fpdecimal.charAt(p) < '0' || fpdecimal.charAt(p) > '9') {
463                 p++;
464                 continue;
465             }
466 
467             striped[q] = fpdecimal.charAt(p);
468             q++;
469             p++;
470             significantDigits++;
471         }
472 
473         // If the decimal point has been found then get rid of trailing zeros.
474         if (decimalFound && q != offset) {
475             for (; ; ) {
476                 q--;
477                 if (q == offset) {
478                     break;
479                 }
480                 if (striped[q] == '0') {
481                     significantDigits--;
482                 } else {
483                     break;
484                 }
485             }
486         }
487 
488         // special case of numbers like "0.00000"
489         if (decimalFound && significantDigits == 0) {
490             decimalPos = 0;
491         }
492 
493         // Implicit decimal point at end of number if not present
494         if (!decimalFound) {
495             decimalPos = q - offset;
496         }
497 
498         // Find the number of significant trailing zeros
499         q = offset; // set q to point to first sig digit
500         p = significantDigits - 1 + offset;
501 
502         while (p > q) {
503             if (striped[p] != '0') {
504                 break;
505             }
506             p--;
507         }
508 
509         // Make sure the decimal is on a mod 10000 boundary
510         int i = ((rsize * 100) - decimalPos - sciexp % rsize) % rsize;
511         q -= i;
512         decimalPos += i;
513 
514         // Make the mantissa length right by adding zeros at the end if necessary
515         while ((p - q) < (mant.length * rsize)) {
516             for (i = 0; i < rsize; i++) {
517                 striped[++p] = '0';
518             }
519         }
520 
521         // Ok, now we know how many trailing zeros there are,
522         // and where the least significant digit is
523         for (i = mant.length - 1; i >= 0; i--) {
524             mant[i] =
525                     (striped[q] - '0') * 1000
526                             + (striped[q + 1] - '0') * 100
527                             + (striped[q + 2] - '0') * 10
528                             + (striped[q + 3] - '0');
529             q += 4;
530         }
531 
532         exp = (decimalPos + sciexp) / rsize;
533 
534         if (q < striped.length) {
535             // Is there possible another digit?
536             round((striped[q] - '0') * 1000);
537         }
538     }
539 
540     /**
541      * Creates an instance with a non-finite value.
542      *
543      * @param field field to which this instance belongs
544      * @param sign sign of the Dfp to create
545      * @param nans code of the value, must be one of {@link #INFINITE}, {@link #SNAN}, {@link #QNAN}
546      */
Dfp(final DfpField field, final byte sign, final byte nans)547     protected Dfp(final DfpField field, final byte sign, final byte nans) {
548         this.field = field;
549         this.mant = new int[field.getRadixDigits()];
550         this.sign = sign;
551         this.exp = 0;
552         this.nans = nans;
553     }
554 
555     /**
556      * Create an instance with a value of 0. Use this internally in preference to constructors to
557      * facilitate subclasses
558      *
559      * @return a new instance with a value of 0
560      */
newInstance()561     public Dfp newInstance() {
562         return new Dfp(getField());
563     }
564 
565     /**
566      * Create an instance from a byte value.
567      *
568      * @param x value to convert to an instance
569      * @return a new instance with value x
570      */
newInstance(final byte x)571     public Dfp newInstance(final byte x) {
572         return new Dfp(getField(), x);
573     }
574 
575     /**
576      * Create an instance from an int value.
577      *
578      * @param x value to convert to an instance
579      * @return a new instance with value x
580      */
newInstance(final int x)581     public Dfp newInstance(final int x) {
582         return new Dfp(getField(), x);
583     }
584 
585     /**
586      * Create an instance from a long value.
587      *
588      * @param x value to convert to an instance
589      * @return a new instance with value x
590      */
newInstance(final long x)591     public Dfp newInstance(final long x) {
592         return new Dfp(getField(), x);
593     }
594 
595     /**
596      * Create an instance from a double value.
597      *
598      * @param x value to convert to an instance
599      * @return a new instance with value x
600      */
newInstance(final double x)601     public Dfp newInstance(final double x) {
602         return new Dfp(getField(), x);
603     }
604 
605     /**
606      * Create an instance by copying an existing one. Use this internally in preference to
607      * constructors to facilitate subclasses.
608      *
609      * @param d instance to copy
610      * @return a new instance with the same value as d
611      */
newInstance(final Dfp d)612     public Dfp newInstance(final Dfp d) {
613 
614         // make sure we don't mix number with different precision
615         if (field.getRadixDigits() != d.field.getRadixDigits()) {
616             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
617             final Dfp result = newInstance(getZero());
618             result.nans = QNAN;
619             return dotrap(DfpField.FLAG_INVALID, NEW_INSTANCE_TRAP, d, result);
620         }
621 
622         return new Dfp(d);
623     }
624 
625     /**
626      * Create an instance from a String representation. Use this internally in preference to
627      * constructors to facilitate subclasses.
628      *
629      * @param s string representation of the instance
630      * @return a new instance parsed from specified string
631      */
newInstance(final String s)632     public Dfp newInstance(final String s) {
633         return new Dfp(field, s);
634     }
635 
636     /**
637      * Creates an instance with a non-finite value.
638      *
639      * @param sig sign of the Dfp to create
640      * @param code code of the value, must be one of {@link #INFINITE}, {@link #SNAN}, {@link #QNAN}
641      * @return a new instance with a non-finite value
642      */
newInstance(final byte sig, final byte code)643     public Dfp newInstance(final byte sig, final byte code) {
644         return field.newDfp(sig, code);
645     }
646 
647     /**
648      * Get the {@link org.apache.commons.math3.Field Field} (really a {@link DfpField}) to which the
649      * instance belongs.
650      *
651      * <p>The field is linked to the number of digits and acts as a factory for {@link Dfp}
652      * instances.
653      *
654      * @return {@link org.apache.commons.math3.Field Field} (really a {@link DfpField}) to which the
655      *     instance belongs
656      */
getField()657     public DfpField getField() {
658         return field;
659     }
660 
661     /**
662      * Get the number of radix digits of the instance.
663      *
664      * @return number of radix digits
665      */
getRadixDigits()666     public int getRadixDigits() {
667         return field.getRadixDigits();
668     }
669 
670     /**
671      * Get the constant 0.
672      *
673      * @return a Dfp with value zero
674      */
getZero()675     public Dfp getZero() {
676         return field.getZero();
677     }
678 
679     /**
680      * Get the constant 1.
681      *
682      * @return a Dfp with value one
683      */
getOne()684     public Dfp getOne() {
685         return field.getOne();
686     }
687 
688     /**
689      * Get the constant 2.
690      *
691      * @return a Dfp with value two
692      */
getTwo()693     public Dfp getTwo() {
694         return field.getTwo();
695     }
696 
697     /** Shift the mantissa left, and adjust the exponent to compensate. */
shiftLeft()698     protected void shiftLeft() {
699         for (int i = mant.length - 1; i > 0; i--) {
700             mant[i] = mant[i - 1];
701         }
702         mant[0] = 0;
703         exp--;
704     }
705 
706     /* Note that shiftRight() does not call round() as that round() itself
707     uses shiftRight() */
708     /** Shift the mantissa right, and adjust the exponent to compensate. */
shiftRight()709     protected void shiftRight() {
710         for (int i = 0; i < mant.length - 1; i++) {
711             mant[i] = mant[i + 1];
712         }
713         mant[mant.length - 1] = 0;
714         exp++;
715     }
716 
717     /**
718      * Make our exp equal to the supplied one, this may cause rounding. Also causes de-normalized
719      * numbers. These numbers are generally dangerous because most routines assume normalized
720      * numbers. Align doesn't round, so it will return the last digit destroyed by shifting right.
721      *
722      * @param e desired exponent
723      * @return last digit destroyed by shifting right
724      */
align(int e)725     protected int align(int e) {
726         int lostdigit = 0;
727         boolean inexact = false;
728 
729         int diff = exp - e;
730 
731         int adiff = diff;
732         if (adiff < 0) {
733             adiff = -adiff;
734         }
735 
736         if (diff == 0) {
737             return 0;
738         }
739 
740         if (adiff > (mant.length + 1)) {
741             // Special case
742             Arrays.fill(mant, 0);
743             exp = e;
744 
745             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
746             dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this);
747 
748             return 0;
749         }
750 
751         for (int i = 0; i < adiff; i++) {
752             if (diff < 0) {
753                 /* Keep track of loss -- only signal inexact after losing 2 digits.
754                  * the first lost digit is returned to add() and may be incorporated
755                  * into the result.
756                  */
757                 if (lostdigit != 0) {
758                     inexact = true;
759                 }
760 
761                 lostdigit = mant[0];
762 
763                 shiftRight();
764             } else {
765                 shiftLeft();
766             }
767         }
768 
769         if (inexact) {
770             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
771             dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this);
772         }
773 
774         return lostdigit;
775     }
776 
777     /**
778      * Check if instance is less than x.
779      *
780      * @param x number to check instance against
781      * @return true if instance is less than x and neither are NaN, false otherwise
782      */
lessThan(final Dfp x)783     public boolean lessThan(final Dfp x) {
784 
785         // make sure we don't mix number with different precision
786         if (field.getRadixDigits() != x.field.getRadixDigits()) {
787             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
788             final Dfp result = newInstance(getZero());
789             result.nans = QNAN;
790             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, result);
791             return false;
792         }
793 
794         /* if a nan is involved, signal invalid and return false */
795         if (isNaN() || x.isNaN()) {
796             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
797             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, newInstance(getZero()));
798             return false;
799         }
800 
801         return compare(this, x) < 0;
802     }
803 
804     /**
805      * Check if instance is greater than x.
806      *
807      * @param x number to check instance against
808      * @return true if instance is greater than x and neither are NaN, false otherwise
809      */
greaterThan(final Dfp x)810     public boolean greaterThan(final Dfp x) {
811 
812         // make sure we don't mix number with different precision
813         if (field.getRadixDigits() != x.field.getRadixDigits()) {
814             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
815             final Dfp result = newInstance(getZero());
816             result.nans = QNAN;
817             dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, result);
818             return false;
819         }
820 
821         /* if a nan is involved, signal invalid and return false */
822         if (isNaN() || x.isNaN()) {
823             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
824             dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, newInstance(getZero()));
825             return false;
826         }
827 
828         return compare(this, x) > 0;
829     }
830 
831     /**
832      * Check if instance is less than or equal to 0.
833      *
834      * @return true if instance is not NaN and less than or equal to 0, false otherwise
835      */
negativeOrNull()836     public boolean negativeOrNull() {
837 
838         if (isNaN()) {
839             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
840             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
841             return false;
842         }
843 
844         return (sign < 0) || ((mant[mant.length - 1] == 0) && !isInfinite());
845     }
846 
847     /**
848      * Check if instance is strictly less than 0.
849      *
850      * @return true if instance is not NaN and less than or equal to 0, false otherwise
851      */
strictlyNegative()852     public boolean strictlyNegative() {
853 
854         if (isNaN()) {
855             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
856             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
857             return false;
858         }
859 
860         return (sign < 0) && ((mant[mant.length - 1] != 0) || isInfinite());
861     }
862 
863     /**
864      * Check if instance is greater than or equal to 0.
865      *
866      * @return true if instance is not NaN and greater than or equal to 0, false otherwise
867      */
positiveOrNull()868     public boolean positiveOrNull() {
869 
870         if (isNaN()) {
871             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
872             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
873             return false;
874         }
875 
876         return (sign > 0) || ((mant[mant.length - 1] == 0) && !isInfinite());
877     }
878 
879     /**
880      * Check if instance is strictly greater than 0.
881      *
882      * @return true if instance is not NaN and greater than or equal to 0, false otherwise
883      */
strictlyPositive()884     public boolean strictlyPositive() {
885 
886         if (isNaN()) {
887             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
888             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
889             return false;
890         }
891 
892         return (sign > 0) && ((mant[mant.length - 1] != 0) || isInfinite());
893     }
894 
895     /**
896      * Get the absolute value of instance.
897      *
898      * @return absolute value of instance
899      * @since 3.2
900      */
abs()901     public Dfp abs() {
902         Dfp result = newInstance(this);
903         result.sign = 1;
904         return result;
905     }
906 
907     /**
908      * Check if instance is infinite.
909      *
910      * @return true if instance is infinite
911      */
isInfinite()912     public boolean isInfinite() {
913         return nans == INFINITE;
914     }
915 
916     /**
917      * Check if instance is not a number.
918      *
919      * @return true if instance is not a number
920      */
isNaN()921     public boolean isNaN() {
922         return (nans == QNAN) || (nans == SNAN);
923     }
924 
925     /**
926      * Check if instance is equal to zero.
927      *
928      * @return true if instance is equal to zero
929      */
isZero()930     public boolean isZero() {
931 
932         if (isNaN()) {
933             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
934             dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, this, newInstance(getZero()));
935             return false;
936         }
937 
938         return (mant[mant.length - 1] == 0) && !isInfinite();
939     }
940 
941     /**
942      * Check if instance is equal to x.
943      *
944      * @param other object to check instance against
945      * @return true if instance is equal to x and neither are NaN, false otherwise
946      */
947     @Override
equals(final Object other)948     public boolean equals(final Object other) {
949 
950         if (other instanceof Dfp) {
951             final Dfp x = (Dfp) other;
952             if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) {
953                 return false;
954             }
955 
956             return compare(this, x) == 0;
957         }
958 
959         return false;
960     }
961 
962     /**
963      * Gets a hashCode for the instance.
964      *
965      * @return a hash code value for this object
966      */
967     @Override
hashCode()968     public int hashCode() {
969         return 17 + (isZero() ? 0 : (sign << 8)) + (nans << 16) + exp + Arrays.hashCode(mant);
970     }
971 
972     /**
973      * Check if instance is not equal to x.
974      *
975      * @param x number to check instance against
976      * @return true if instance is not equal to x and neither are NaN, false otherwise
977      */
unequal(final Dfp x)978     public boolean unequal(final Dfp x) {
979         if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) {
980             return false;
981         }
982 
983         return greaterThan(x) || lessThan(x);
984     }
985 
986     /**
987      * Compare two instances.
988      *
989      * @param a first instance in comparison
990      * @param b second instance in comparison
991      * @return -1 if a<b, 1 if a>b and 0 if a==b Note this method does not properly handle NaNs or
992      *     numbers with different precision.
993      */
compare(final Dfp a, final Dfp b)994     private static int compare(final Dfp a, final Dfp b) {
995         // Ignore the sign of zero
996         if (a.mant[a.mant.length - 1] == 0
997                 && b.mant[b.mant.length - 1] == 0
998                 && a.nans == FINITE
999                 && b.nans == FINITE) {
1000             return 0;
1001         }
1002 
1003         if (a.sign != b.sign) {
1004             if (a.sign == -1) {
1005                 return -1;
1006             } else {
1007                 return 1;
1008             }
1009         }
1010 
1011         // deal with the infinities
1012         if (a.nans == INFINITE && b.nans == FINITE) {
1013             return a.sign;
1014         }
1015 
1016         if (a.nans == FINITE && b.nans == INFINITE) {
1017             return -b.sign;
1018         }
1019 
1020         if (a.nans == INFINITE && b.nans == INFINITE) {
1021             return 0;
1022         }
1023 
1024         // Handle special case when a or b is zero, by ignoring the exponents
1025         if (b.mant[b.mant.length - 1] != 0 && a.mant[b.mant.length - 1] != 0) {
1026             if (a.exp < b.exp) {
1027                 return -a.sign;
1028             }
1029 
1030             if (a.exp > b.exp) {
1031                 return a.sign;
1032             }
1033         }
1034 
1035         // compare the mantissas
1036         for (int i = a.mant.length - 1; i >= 0; i--) {
1037             if (a.mant[i] > b.mant[i]) {
1038                 return a.sign;
1039             }
1040 
1041             if (a.mant[i] < b.mant[i]) {
1042                 return -a.sign;
1043             }
1044         }
1045 
1046         return 0;
1047     }
1048 
1049     /**
1050      * Round to nearest integer using the round-half-even method. That is round to nearest integer
1051      * unless both are equidistant. In which case round to the even one.
1052      *
1053      * @return rounded value
1054      * @since 3.2
1055      */
rint()1056     public Dfp rint() {
1057         return trunc(DfpField.RoundingMode.ROUND_HALF_EVEN);
1058     }
1059 
1060     /**
1061      * Round to an integer using the round floor mode. That is, round toward -Infinity
1062      *
1063      * @return rounded value
1064      * @since 3.2
1065      */
floor()1066     public Dfp floor() {
1067         return trunc(DfpField.RoundingMode.ROUND_FLOOR);
1068     }
1069 
1070     /**
1071      * Round to an integer using the round ceil mode. That is, round toward +Infinity
1072      *
1073      * @return rounded value
1074      * @since 3.2
1075      */
ceil()1076     public Dfp ceil() {
1077         return trunc(DfpField.RoundingMode.ROUND_CEIL);
1078     }
1079 
1080     /**
1081      * Returns the IEEE remainder.
1082      *
1083      * @param d divisor
1084      * @return this less n &times; d, where n is the integer closest to this/d
1085      * @since 3.2
1086      */
remainder(final Dfp d)1087     public Dfp remainder(final Dfp d) {
1088 
1089         final Dfp result = this.subtract(this.divide(d).rint().multiply(d));
1090 
1091         // IEEE 854-1987 says that if the result is zero, then it carries the sign of this
1092         if (result.mant[mant.length - 1] == 0) {
1093             result.sign = sign;
1094         }
1095 
1096         return result;
1097     }
1098 
1099     /**
1100      * Does the integer conversions with the specified rounding.
1101      *
1102      * @param rmode rounding mode to use
1103      * @return truncated value
1104      */
trunc(final DfpField.RoundingMode rmode)1105     protected Dfp trunc(final DfpField.RoundingMode rmode) {
1106         boolean changed = false;
1107 
1108         if (isNaN()) {
1109             return newInstance(this);
1110         }
1111 
1112         if (nans == INFINITE) {
1113             return newInstance(this);
1114         }
1115 
1116         if (mant[mant.length - 1] == 0) {
1117             // a is zero
1118             return newInstance(this);
1119         }
1120 
1121         /* If the exponent is less than zero then we can certainly
1122          * return zero */
1123         if (exp < 0) {
1124             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
1125             Dfp result = newInstance(getZero());
1126             result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
1127             return result;
1128         }
1129 
1130         /* If the exponent is greater than or equal to digits, then it
1131          * must already be an integer since there is no precision left
1132          * for any fractional part */
1133 
1134         if (exp >= mant.length) {
1135             return newInstance(this);
1136         }
1137 
1138         /* General case:  create another dfp, result, that contains the
1139          * a with the fractional part lopped off.  */
1140 
1141         Dfp result = newInstance(this);
1142         for (int i = 0; i < mant.length - result.exp; i++) {
1143             changed |= result.mant[i] != 0;
1144             result.mant[i] = 0;
1145         }
1146 
1147         if (changed) {
1148             switch (rmode) {
1149                 case ROUND_FLOOR:
1150                     if (result.sign == -1) {
1151                         // then we must increment the mantissa by one
1152                         result = result.add(newInstance(-1));
1153                     }
1154                     break;
1155 
1156                 case ROUND_CEIL:
1157                     if (result.sign == 1) {
1158                         // then we must increment the mantissa by one
1159                         result = result.add(getOne());
1160                     }
1161                     break;
1162 
1163                 case ROUND_HALF_EVEN:
1164                 default:
1165                     final Dfp half = newInstance("0.5");
1166                     Dfp a = subtract(result); // difference between this and result
1167                     a.sign = 1; // force positive (take abs)
1168                     if (a.greaterThan(half)) {
1169                         a = newInstance(getOne());
1170                         a.sign = sign;
1171                         result = result.add(a);
1172                     }
1173 
1174                     /** If exactly equal to 1/2 and odd then increment */
1175                     if (a.equals(half)
1176                             && result.exp > 0
1177                             && (result.mant[mant.length - result.exp] & 1) != 0) {
1178                         a = newInstance(getOne());
1179                         a.sign = sign;
1180                         result = result.add(a);
1181                     }
1182                     break;
1183             }
1184 
1185             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); // signal inexact
1186             result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
1187             return result;
1188         }
1189 
1190         return result;
1191     }
1192 
1193     /**
1194      * Convert this to an integer. If greater than 2147483647, it returns 2147483647. If less than
1195      * -2147483648 it returns -2147483648.
1196      *
1197      * @return converted number
1198      */
intValue()1199     public int intValue() {
1200         Dfp rounded;
1201         int result = 0;
1202 
1203         rounded = rint();
1204 
1205         if (rounded.greaterThan(newInstance(2147483647))) {
1206             return 2147483647;
1207         }
1208 
1209         if (rounded.lessThan(newInstance(-2147483648))) {
1210             return -2147483648;
1211         }
1212 
1213         for (int i = mant.length - 1; i >= mant.length - rounded.exp; i--) {
1214             result = result * RADIX + rounded.mant[i];
1215         }
1216 
1217         if (rounded.sign == -1) {
1218             result = -result;
1219         }
1220 
1221         return result;
1222     }
1223 
1224     /**
1225      * Get the exponent of the greatest power of 10000 that is less than or equal to the absolute
1226      * value of this. I.E. if this is 10<sup>6</sup> then log10K would return 1.
1227      *
1228      * @return integer base 10000 logarithm
1229      */
log10K()1230     public int log10K() {
1231         return exp - 1;
1232     }
1233 
1234     /**
1235      * Get the specified power of 10000.
1236      *
1237      * @param e desired power
1238      * @return 10000<sup>e</sup>
1239      */
power10K(final int e)1240     public Dfp power10K(final int e) {
1241         Dfp d = newInstance(getOne());
1242         d.exp = e + 1;
1243         return d;
1244     }
1245 
1246     /**
1247      * Get the exponent of the greatest power of 10 that is less than or equal to abs(this).
1248      *
1249      * @return integer base 10 logarithm
1250      * @since 3.2
1251      */
intLog10()1252     public int intLog10() {
1253         if (mant[mant.length - 1] > 1000) {
1254             return exp * 4 - 1;
1255         }
1256         if (mant[mant.length - 1] > 100) {
1257             return exp * 4 - 2;
1258         }
1259         if (mant[mant.length - 1] > 10) {
1260             return exp * 4 - 3;
1261         }
1262         return exp * 4 - 4;
1263     }
1264 
1265     /**
1266      * Return the specified power of 10.
1267      *
1268      * @param e desired power
1269      * @return 10<sup>e</sup>
1270      */
power10(final int e)1271     public Dfp power10(final int e) {
1272         Dfp d = newInstance(getOne());
1273 
1274         if (e >= 0) {
1275             d.exp = e / 4 + 1;
1276         } else {
1277             d.exp = (e + 1) / 4;
1278         }
1279 
1280         switch ((e % 4 + 4) % 4) {
1281             case 0:
1282                 break;
1283             case 1:
1284                 d = d.multiply(10);
1285                 break;
1286             case 2:
1287                 d = d.multiply(100);
1288                 break;
1289             default:
1290                 d = d.multiply(1000);
1291         }
1292 
1293         return d;
1294     }
1295 
1296     /**
1297      * Negate the mantissa of this by computing the complement. Leaves the sign bit unchanged, used
1298      * internally by add. Denormalized numbers are handled properly here.
1299      *
1300      * @param extra ???
1301      * @return ???
1302      */
complement(int extra)1303     protected int complement(int extra) {
1304 
1305         extra = RADIX - extra;
1306         for (int i = 0; i < mant.length; i++) {
1307             mant[i] = RADIX - mant[i] - 1;
1308         }
1309 
1310         int rh = extra / RADIX;
1311         extra -= rh * RADIX;
1312         for (int i = 0; i < mant.length; i++) {
1313             final int r = mant[i] + rh;
1314             rh = r / RADIX;
1315             mant[i] = r - rh * RADIX;
1316         }
1317 
1318         return extra;
1319     }
1320 
1321     /**
1322      * Add x to this.
1323      *
1324      * @param x number to add
1325      * @return sum of this and x
1326      */
add(final Dfp x)1327     public Dfp add(final Dfp x) {
1328 
1329         // make sure we don't mix number with different precision
1330         if (field.getRadixDigits() != x.field.getRadixDigits()) {
1331             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
1332             final Dfp result = newInstance(getZero());
1333             result.nans = QNAN;
1334             return dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result);
1335         }
1336 
1337         /* handle special cases */
1338         if (nans != FINITE || x.nans != FINITE) {
1339             if (isNaN()) {
1340                 return this;
1341             }
1342 
1343             if (x.isNaN()) {
1344                 return x;
1345             }
1346 
1347             if (nans == INFINITE && x.nans == FINITE) {
1348                 return this;
1349             }
1350 
1351             if (x.nans == INFINITE && nans == FINITE) {
1352                 return x;
1353             }
1354 
1355             if (x.nans == INFINITE && nans == INFINITE && sign == x.sign) {
1356                 return x;
1357             }
1358 
1359             if (x.nans == INFINITE && nans == INFINITE && sign != x.sign) {
1360                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
1361                 Dfp result = newInstance(getZero());
1362                 result.nans = QNAN;
1363                 result = dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result);
1364                 return result;
1365             }
1366         }
1367 
1368         /* copy this and the arg */
1369         Dfp a = newInstance(this);
1370         Dfp b = newInstance(x);
1371 
1372         /* initialize the result object */
1373         Dfp result = newInstance(getZero());
1374 
1375         /* Make all numbers positive, but remember their sign */
1376         final byte asign = a.sign;
1377         final byte bsign = b.sign;
1378 
1379         a.sign = 1;
1380         b.sign = 1;
1381 
1382         /* The result will be signed like the arg with greatest magnitude */
1383         byte rsign = bsign;
1384         if (compare(a, b) > 0) {
1385             rsign = asign;
1386         }
1387 
1388         /* Handle special case when a or b is zero, by setting the exponent
1389         of the zero number equal to the other one.  This avoids an alignment
1390         which would cause catastropic loss of precision */
1391         if (b.mant[mant.length - 1] == 0) {
1392             b.exp = a.exp;
1393         }
1394 
1395         if (a.mant[mant.length - 1] == 0) {
1396             a.exp = b.exp;
1397         }
1398 
1399         /* align number with the smaller exponent */
1400         int aextradigit = 0;
1401         int bextradigit = 0;
1402         if (a.exp < b.exp) {
1403             aextradigit = a.align(b.exp);
1404         } else {
1405             bextradigit = b.align(a.exp);
1406         }
1407 
1408         /* complement the smaller of the two if the signs are different */
1409         if (asign != bsign) {
1410             if (asign == rsign) {
1411                 bextradigit = b.complement(bextradigit);
1412             } else {
1413                 aextradigit = a.complement(aextradigit);
1414             }
1415         }
1416 
1417         /* add the mantissas */
1418         int rh = 0; /* acts as a carry */
1419         for (int i = 0; i < mant.length; i++) {
1420             final int r = a.mant[i] + b.mant[i] + rh;
1421             rh = r / RADIX;
1422             result.mant[i] = r - rh * RADIX;
1423         }
1424         result.exp = a.exp;
1425         result.sign = rsign;
1426 
1427         /* handle overflow -- note, when asign!=bsign an overflow is
1428          * normal and should be ignored.  */
1429 
1430         if (rh != 0 && (asign == bsign)) {
1431             final int lostdigit = result.mant[0];
1432             result.shiftRight();
1433             result.mant[mant.length - 1] = rh;
1434             final int excp = result.round(lostdigit);
1435             if (excp != 0) {
1436                 result = dotrap(excp, ADD_TRAP, x, result);
1437             }
1438         }
1439 
1440         /* normalize the result */
1441         for (int i = 0; i < mant.length; i++) {
1442             if (result.mant[mant.length - 1] != 0) {
1443                 break;
1444             }
1445             result.shiftLeft();
1446             if (i == 0) {
1447                 result.mant[0] = aextradigit + bextradigit;
1448                 aextradigit = 0;
1449                 bextradigit = 0;
1450             }
1451         }
1452 
1453         /* result is zero if after normalization the most sig. digit is zero */
1454         if (result.mant[mant.length - 1] == 0) {
1455             result.exp = 0;
1456 
1457             if (asign != bsign) {
1458                 // Unless adding 2 negative zeros, sign is positive
1459                 result.sign = 1; // Per IEEE 854-1987 Section 6.3
1460             }
1461         }
1462 
1463         /* Call round to test for over/under flows */
1464         final int excp = result.round(aextradigit + bextradigit);
1465         if (excp != 0) {
1466             result = dotrap(excp, ADD_TRAP, x, result);
1467         }
1468 
1469         return result;
1470     }
1471 
1472     /**
1473      * Returns a number that is this number with the sign bit reversed.
1474      *
1475      * @return the opposite of this
1476      */
negate()1477     public Dfp negate() {
1478         Dfp result = newInstance(this);
1479         result.sign = (byte) -result.sign;
1480         return result;
1481     }
1482 
1483     /**
1484      * Subtract x from this.
1485      *
1486      * @param x number to subtract
1487      * @return difference of this and a
1488      */
subtract(final Dfp x)1489     public Dfp subtract(final Dfp x) {
1490         return add(x.negate());
1491     }
1492 
1493     /**
1494      * Round this given the next digit n using the current rounding mode.
1495      *
1496      * @param n ???
1497      * @return the IEEE flag if an exception occurred
1498      */
round(int n)1499     protected int round(int n) {
1500         boolean inc = false;
1501         switch (field.getRoundingMode()) {
1502             case ROUND_DOWN:
1503                 inc = false;
1504                 break;
1505 
1506             case ROUND_UP:
1507                 inc = n != 0; // round up if n!=0
1508                 break;
1509 
1510             case ROUND_HALF_UP:
1511                 inc = n >= 5000; // round half up
1512                 break;
1513 
1514             case ROUND_HALF_DOWN:
1515                 inc = n > 5000; // round half down
1516                 break;
1517 
1518             case ROUND_HALF_EVEN:
1519                 inc = n > 5000 || (n == 5000 && (mant[0] & 1) == 1); // round half-even
1520                 break;
1521 
1522             case ROUND_HALF_ODD:
1523                 inc = n > 5000 || (n == 5000 && (mant[0] & 1) == 0); // round half-odd
1524                 break;
1525 
1526             case ROUND_CEIL:
1527                 inc = sign == 1 && n != 0; // round ceil
1528                 break;
1529 
1530             case ROUND_FLOOR:
1531             default:
1532                 inc = sign == -1 && n != 0; // round floor
1533                 break;
1534         }
1535 
1536         if (inc) {
1537             // increment if necessary
1538             int rh = 1;
1539             for (int i = 0; i < mant.length; i++) {
1540                 final int r = mant[i] + rh;
1541                 rh = r / RADIX;
1542                 mant[i] = r - rh * RADIX;
1543             }
1544 
1545             if (rh != 0) {
1546                 shiftRight();
1547                 mant[mant.length - 1] = rh;
1548             }
1549         }
1550 
1551         // check for exceptional cases and raise signals if necessary
1552         if (exp < MIN_EXP) {
1553             // Gradual Underflow
1554             field.setIEEEFlagsBits(DfpField.FLAG_UNDERFLOW);
1555             return DfpField.FLAG_UNDERFLOW;
1556         }
1557 
1558         if (exp > MAX_EXP) {
1559             // Overflow
1560             field.setIEEEFlagsBits(DfpField.FLAG_OVERFLOW);
1561             return DfpField.FLAG_OVERFLOW;
1562         }
1563 
1564         if (n != 0) {
1565             // Inexact
1566             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
1567             return DfpField.FLAG_INEXACT;
1568         }
1569 
1570         return 0;
1571     }
1572 
1573     /**
1574      * Multiply this by x.
1575      *
1576      * @param x multiplicand
1577      * @return product of this and x
1578      */
multiply(final Dfp x)1579     public Dfp multiply(final Dfp x) {
1580 
1581         // make sure we don't mix number with different precision
1582         if (field.getRadixDigits() != x.field.getRadixDigits()) {
1583             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
1584             final Dfp result = newInstance(getZero());
1585             result.nans = QNAN;
1586             return dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result);
1587         }
1588 
1589         Dfp result = newInstance(getZero());
1590 
1591         /* handle special cases */
1592         if (nans != FINITE || x.nans != FINITE) {
1593             if (isNaN()) {
1594                 return this;
1595             }
1596 
1597             if (x.isNaN()) {
1598                 return x;
1599             }
1600 
1601             if (nans == INFINITE && x.nans == FINITE && x.mant[mant.length - 1] != 0) {
1602                 result = newInstance(this);
1603                 result.sign = (byte) (sign * x.sign);
1604                 return result;
1605             }
1606 
1607             if (x.nans == INFINITE && nans == FINITE && mant[mant.length - 1] != 0) {
1608                 result = newInstance(x);
1609                 result.sign = (byte) (sign * x.sign);
1610                 return result;
1611             }
1612 
1613             if (x.nans == INFINITE && nans == INFINITE) {
1614                 result = newInstance(this);
1615                 result.sign = (byte) (sign * x.sign);
1616                 return result;
1617             }
1618 
1619             if ((x.nans == INFINITE && nans == FINITE && mant[mant.length - 1] == 0)
1620                     || (nans == INFINITE && x.nans == FINITE && x.mant[mant.length - 1] == 0)) {
1621                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
1622                 result = newInstance(getZero());
1623                 result.nans = QNAN;
1624                 result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result);
1625                 return result;
1626             }
1627         }
1628 
1629         int[] product = new int[mant.length * 2]; // Big enough to hold even the largest result
1630 
1631         for (int i = 0; i < mant.length; i++) {
1632             int rh = 0; // acts as a carry
1633             for (int j = 0; j < mant.length; j++) {
1634                 int r = mant[i] * x.mant[j]; // multiply the 2 digits
1635                 r += product[i + j] + rh; // add to the product digit with carry in
1636 
1637                 rh = r / RADIX;
1638                 product[i + j] = r - rh * RADIX;
1639             }
1640             product[i + mant.length] = rh;
1641         }
1642 
1643         // Find the most sig digit
1644         int md = mant.length * 2 - 1; // default, in case result is zero
1645         for (int i = mant.length * 2 - 1; i >= 0; i--) {
1646             if (product[i] != 0) {
1647                 md = i;
1648                 break;
1649             }
1650         }
1651 
1652         // Copy the digits into the result
1653         for (int i = 0; i < mant.length; i++) {
1654             result.mant[mant.length - i - 1] = product[md - i];
1655         }
1656 
1657         // Fixup the exponent.
1658         result.exp = exp + x.exp + md - 2 * mant.length + 1;
1659         result.sign = (byte) ((sign == x.sign) ? 1 : -1);
1660 
1661         if (result.mant[mant.length - 1] == 0) {
1662             // if result is zero, set exp to zero
1663             result.exp = 0;
1664         }
1665 
1666         final int excp;
1667         if (md > (mant.length - 1)) {
1668             excp = result.round(product[md - mant.length]);
1669         } else {
1670             excp = result.round(0); // has no effect except to check status
1671         }
1672 
1673         if (excp != 0) {
1674             result = dotrap(excp, MULTIPLY_TRAP, x, result);
1675         }
1676 
1677         return result;
1678     }
1679 
1680     /**
1681      * Multiply this by a single digit x.
1682      *
1683      * @param x multiplicand
1684      * @return product of this and x
1685      */
multiply(final int x)1686     public Dfp multiply(final int x) {
1687         if (x >= 0 && x < RADIX) {
1688             return multiplyFast(x);
1689         } else {
1690             return multiply(newInstance(x));
1691         }
1692     }
1693 
1694     /**
1695      * Multiply this by a single digit 0&lt;=x&lt;radix. There are speed advantages in this special
1696      * case.
1697      *
1698      * @param x multiplicand
1699      * @return product of this and x
1700      */
multiplyFast(final int x)1701     private Dfp multiplyFast(final int x) {
1702         Dfp result = newInstance(this);
1703 
1704         /* handle special cases */
1705         if (nans != FINITE) {
1706             if (isNaN()) {
1707                 return this;
1708             }
1709 
1710             if (nans == INFINITE && x != 0) {
1711                 result = newInstance(this);
1712                 return result;
1713             }
1714 
1715             if (nans == INFINITE && x == 0) {
1716                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
1717                 result = newInstance(getZero());
1718                 result.nans = QNAN;
1719                 result =
1720                         dotrap(
1721                                 DfpField.FLAG_INVALID,
1722                                 MULTIPLY_TRAP,
1723                                 newInstance(getZero()),
1724                                 result);
1725                 return result;
1726             }
1727         }
1728 
1729         /* range check x */
1730         if (x < 0 || x >= RADIX) {
1731             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
1732             result = newInstance(getZero());
1733             result.nans = QNAN;
1734             result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, result, result);
1735             return result;
1736         }
1737 
1738         int rh = 0;
1739         for (int i = 0; i < mant.length; i++) {
1740             final int r = mant[i] * x + rh;
1741             rh = r / RADIX;
1742             result.mant[i] = r - rh * RADIX;
1743         }
1744 
1745         int lostdigit = 0;
1746         if (rh != 0) {
1747             lostdigit = result.mant[0];
1748             result.shiftRight();
1749             result.mant[mant.length - 1] = rh;
1750         }
1751 
1752         if (result.mant[mant.length - 1] == 0) { // if result is zero, set exp to zero
1753             result.exp = 0;
1754         }
1755 
1756         final int excp = result.round(lostdigit);
1757         if (excp != 0) {
1758             result = dotrap(excp, MULTIPLY_TRAP, result, result);
1759         }
1760 
1761         return result;
1762     }
1763 
1764     /**
1765      * Divide this by divisor.
1766      *
1767      * @param divisor divisor
1768      * @return quotient of this by divisor
1769      */
divide(Dfp divisor)1770     public Dfp divide(Dfp divisor) {
1771         int dividend[]; // current status of the dividend
1772         int quotient[]; // quotient
1773         int remainder[]; // remainder
1774         int qd; // current quotient digit we're working with
1775         int nsqd; // number of significant quotient digits we have
1776         int trial = 0; // trial quotient digit
1777         int minadj; // minimum adjustment
1778         boolean trialgood; // Flag to indicate a good trail digit
1779         int md = 0; // most sig digit in result
1780         int excp; // exceptions
1781 
1782         // make sure we don't mix number with different precision
1783         if (field.getRadixDigits() != divisor.field.getRadixDigits()) {
1784             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
1785             final Dfp result = newInstance(getZero());
1786             result.nans = QNAN;
1787             return dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result);
1788         }
1789 
1790         Dfp result = newInstance(getZero());
1791 
1792         /* handle special cases */
1793         if (nans != FINITE || divisor.nans != FINITE) {
1794             if (isNaN()) {
1795                 return this;
1796             }
1797 
1798             if (divisor.isNaN()) {
1799                 return divisor;
1800             }
1801 
1802             if (nans == INFINITE && divisor.nans == FINITE) {
1803                 result = newInstance(this);
1804                 result.sign = (byte) (sign * divisor.sign);
1805                 return result;
1806             }
1807 
1808             if (divisor.nans == INFINITE && nans == FINITE) {
1809                 result = newInstance(getZero());
1810                 result.sign = (byte) (sign * divisor.sign);
1811                 return result;
1812             }
1813 
1814             if (divisor.nans == INFINITE && nans == INFINITE) {
1815                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
1816                 result = newInstance(getZero());
1817                 result.nans = QNAN;
1818                 result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result);
1819                 return result;
1820             }
1821         }
1822 
1823         /* Test for divide by zero */
1824         if (divisor.mant[mant.length - 1] == 0) {
1825             field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO);
1826             result = newInstance(getZero());
1827             result.sign = (byte) (sign * divisor.sign);
1828             result.nans = INFINITE;
1829             result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, divisor, result);
1830             return result;
1831         }
1832 
1833         dividend = new int[mant.length + 1]; // one extra digit needed
1834         quotient =
1835                 new int[mant.length + 2]; // two extra digits needed 1 for overflow, 1 for rounding
1836         remainder = new int[mant.length + 1]; // one extra digit needed
1837 
1838         /* Initialize our most significant digits to zero */
1839 
1840         dividend[mant.length] = 0;
1841         quotient[mant.length] = 0;
1842         quotient[mant.length + 1] = 0;
1843         remainder[mant.length] = 0;
1844 
1845         /* copy our mantissa into the dividend, initialize the
1846         quotient while we are at it */
1847 
1848         for (int i = 0; i < mant.length; i++) {
1849             dividend[i] = mant[i];
1850             quotient[i] = 0;
1851             remainder[i] = 0;
1852         }
1853 
1854         /* outer loop.  Once per quotient digit */
1855         nsqd = 0;
1856         for (qd = mant.length + 1; qd >= 0; qd--) {
1857             /* Determine outer limits of our quotient digit */
1858 
1859             // r =  most sig 2 digits of dividend
1860             final int divMsb = dividend[mant.length] * RADIX + dividend[mant.length - 1];
1861             int min = divMsb / (divisor.mant[mant.length - 1] + 1);
1862             int max = (divMsb + 1) / divisor.mant[mant.length - 1];
1863 
1864             trialgood = false;
1865             while (!trialgood) {
1866                 // try the mean
1867                 trial = (min + max) / 2;
1868 
1869                 /* Multiply by divisor and store as remainder */
1870                 int rh = 0;
1871                 for (int i = 0; i < mant.length + 1; i++) {
1872                     int dm = (i < mant.length) ? divisor.mant[i] : 0;
1873                     final int r = (dm * trial) + rh;
1874                     rh = r / RADIX;
1875                     remainder[i] = r - rh * RADIX;
1876                 }
1877 
1878                 /* subtract the remainder from the dividend */
1879                 rh = 1; // carry in to aid the subtraction
1880                 for (int i = 0; i < mant.length + 1; i++) {
1881                     final int r = ((RADIX - 1) - remainder[i]) + dividend[i] + rh;
1882                     rh = r / RADIX;
1883                     remainder[i] = r - rh * RADIX;
1884                 }
1885 
1886                 /* Lets analyze what we have here */
1887                 if (rh == 0) {
1888                     // trial is too big -- negative remainder
1889                     max = trial - 1;
1890                     continue;
1891                 }
1892 
1893                 /* find out how far off the remainder is telling us we are */
1894                 minadj = (remainder[mant.length] * RADIX) + remainder[mant.length - 1];
1895                 minadj /= divisor.mant[mant.length - 1] + 1;
1896 
1897                 if (minadj >= 2) {
1898                     min = trial + minadj; // update the minimum
1899                     continue;
1900                 }
1901 
1902                 /* May have a good one here, check more thoroughly.  Basically
1903                 its a good one if it is less than the divisor */
1904                 trialgood = false; // assume false
1905                 for (int i = mant.length - 1; i >= 0; i--) {
1906                     if (divisor.mant[i] > remainder[i]) {
1907                         trialgood = true;
1908                     }
1909                     if (divisor.mant[i] < remainder[i]) {
1910                         break;
1911                     }
1912                 }
1913 
1914                 if (remainder[mant.length] != 0) {
1915                     trialgood = false;
1916                 }
1917 
1918                 if (trialgood == false) {
1919                     min = trial + 1;
1920                 }
1921             }
1922 
1923             /* Great we have a digit! */
1924             quotient[qd] = trial;
1925             if (trial != 0 || nsqd != 0) {
1926                 nsqd++;
1927             }
1928 
1929             if (field.getRoundingMode() == DfpField.RoundingMode.ROUND_DOWN
1930                     && nsqd == mant.length) {
1931                 // We have enough for this mode
1932                 break;
1933             }
1934 
1935             if (nsqd > mant.length) {
1936                 // We have enough digits
1937                 break;
1938             }
1939 
1940             /* move the remainder into the dividend while left shifting */
1941             dividend[0] = 0;
1942             for (int i = 0; i < mant.length; i++) {
1943                 dividend[i + 1] = remainder[i];
1944             }
1945         }
1946 
1947         /* Find the most sig digit */
1948         md = mant.length; // default
1949         for (int i = mant.length + 1; i >= 0; i--) {
1950             if (quotient[i] != 0) {
1951                 md = i;
1952                 break;
1953             }
1954         }
1955 
1956         /* Copy the digits into the result */
1957         for (int i = 0; i < mant.length; i++) {
1958             result.mant[mant.length - i - 1] = quotient[md - i];
1959         }
1960 
1961         /* Fixup the exponent. */
1962         result.exp = exp - divisor.exp + md - mant.length;
1963         result.sign = (byte) ((sign == divisor.sign) ? 1 : -1);
1964 
1965         if (result.mant[mant.length - 1] == 0) { // if result is zero, set exp to zero
1966             result.exp = 0;
1967         }
1968 
1969         if (md > (mant.length - 1)) {
1970             excp = result.round(quotient[md - mant.length]);
1971         } else {
1972             excp = result.round(0);
1973         }
1974 
1975         if (excp != 0) {
1976             result = dotrap(excp, DIVIDE_TRAP, divisor, result);
1977         }
1978 
1979         return result;
1980     }
1981 
1982     /**
1983      * Divide by a single digit less than radix. Special case, so there are speed advantages. 0
1984      * &lt;= divisor &lt; radix
1985      *
1986      * @param divisor divisor
1987      * @return quotient of this by divisor
1988      */
divide(int divisor)1989     public Dfp divide(int divisor) {
1990 
1991         // Handle special cases
1992         if (nans != FINITE) {
1993             if (isNaN()) {
1994                 return this;
1995             }
1996 
1997             if (nans == INFINITE) {
1998                 return newInstance(this);
1999             }
2000         }
2001 
2002         // Test for divide by zero
2003         if (divisor == 0) {
2004             field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO);
2005             Dfp result = newInstance(getZero());
2006             result.sign = sign;
2007             result.nans = INFINITE;
2008             result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, getZero(), result);
2009             return result;
2010         }
2011 
2012         // range check divisor
2013         if (divisor < 0 || divisor >= RADIX) {
2014             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
2015             Dfp result = newInstance(getZero());
2016             result.nans = QNAN;
2017             result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, result, result);
2018             return result;
2019         }
2020 
2021         Dfp result = newInstance(this);
2022 
2023         int rl = 0;
2024         for (int i = mant.length - 1; i >= 0; i--) {
2025             final int r = rl * RADIX + result.mant[i];
2026             final int rh = r / divisor;
2027             rl = r - rh * divisor;
2028             result.mant[i] = rh;
2029         }
2030 
2031         if (result.mant[mant.length - 1] == 0) {
2032             // normalize
2033             result.shiftLeft();
2034             final int r = rl * RADIX; // compute the next digit and put it in
2035             final int rh = r / divisor;
2036             rl = r - rh * divisor;
2037             result.mant[0] = rh;
2038         }
2039 
2040         final int excp = result.round(rl * RADIX / divisor); // do the rounding
2041         if (excp != 0) {
2042             result = dotrap(excp, DIVIDE_TRAP, result, result);
2043         }
2044 
2045         return result;
2046     }
2047 
2048     /** {@inheritDoc} */
reciprocal()2049     public Dfp reciprocal() {
2050         return field.getOne().divide(this);
2051     }
2052 
2053     /**
2054      * Compute the square root.
2055      *
2056      * @return square root of the instance
2057      * @since 3.2
2058      */
sqrt()2059     public Dfp sqrt() {
2060 
2061         // check for unusual cases
2062         if (nans == FINITE && mant[mant.length - 1] == 0) {
2063             // if zero
2064             return newInstance(this);
2065         }
2066 
2067         if (nans != FINITE) {
2068             if (nans == INFINITE && sign == 1) {
2069                 // if positive infinity
2070                 return newInstance(this);
2071             }
2072 
2073             if (nans == QNAN) {
2074                 return newInstance(this);
2075             }
2076 
2077             if (nans == SNAN) {
2078                 Dfp result;
2079 
2080                 field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
2081                 result = newInstance(this);
2082                 result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result);
2083                 return result;
2084             }
2085         }
2086 
2087         if (sign == -1) {
2088             // if negative
2089             Dfp result;
2090 
2091             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
2092             result = newInstance(this);
2093             result.nans = QNAN;
2094             result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result);
2095             return result;
2096         }
2097 
2098         Dfp x = newInstance(this);
2099 
2100         /* Lets make a reasonable guess as to the size of the square root */
2101         if (x.exp < -1 || x.exp > 1) {
2102             x.exp = this.exp / 2;
2103         }
2104 
2105         /* Coarsely estimate the mantissa */
2106         switch (x.mant[mant.length - 1] / 2000) {
2107             case 0:
2108                 x.mant[mant.length - 1] = x.mant[mant.length - 1] / 2 + 1;
2109                 break;
2110             case 2:
2111                 x.mant[mant.length - 1] = 1500;
2112                 break;
2113             case 3:
2114                 x.mant[mant.length - 1] = 2200;
2115                 break;
2116             default:
2117                 x.mant[mant.length - 1] = 3000;
2118         }
2119 
2120         Dfp dx = newInstance(x);
2121 
2122         /* Now that we have the first pass estimate, compute the rest
2123         by the formula dx = (y - x*x) / (2x); */
2124 
2125         Dfp px = getZero();
2126         Dfp ppx = getZero();
2127         while (x.unequal(px)) {
2128             dx = newInstance(x);
2129             dx.sign = -1;
2130             dx = dx.add(this.divide(x));
2131             dx = dx.divide(2);
2132             ppx = px;
2133             px = x;
2134             x = x.add(dx);
2135 
2136             if (x.equals(ppx)) {
2137                 // alternating between two values
2138                 break;
2139             }
2140 
2141             // if dx is zero, break.  Note testing the most sig digit
2142             // is a sufficient test since dx is normalized
2143             if (dx.mant[mant.length - 1] == 0) {
2144                 break;
2145             }
2146         }
2147 
2148         return x;
2149     }
2150 
2151     /**
2152      * Get a string representation of the instance.
2153      *
2154      * @return string representation of the instance
2155      */
2156     @Override
toString()2157     public String toString() {
2158         if (nans != FINITE) {
2159             // if non-finite exceptional cases
2160             if (nans == INFINITE) {
2161                 return (sign < 0) ? NEG_INFINITY_STRING : POS_INFINITY_STRING;
2162             } else {
2163                 return NAN_STRING;
2164             }
2165         }
2166 
2167         if (exp > mant.length || exp < -1) {
2168             return dfp2sci();
2169         }
2170 
2171         return dfp2string();
2172     }
2173 
2174     /**
2175      * Convert an instance to a string using scientific notation.
2176      *
2177      * @return string representation of the instance in scientific notation
2178      */
dfp2sci()2179     protected String dfp2sci() {
2180         char rawdigits[] = new char[mant.length * 4];
2181         char outputbuffer[] = new char[mant.length * 4 + 20];
2182         int p;
2183         int q;
2184         int e;
2185         int ae;
2186         int shf;
2187 
2188         // Get all the digits
2189         p = 0;
2190         for (int i = mant.length - 1; i >= 0; i--) {
2191             rawdigits[p++] = (char) ((mant[i] / 1000) + '0');
2192             rawdigits[p++] = (char) (((mant[i] / 100) % 10) + '0');
2193             rawdigits[p++] = (char) (((mant[i] / 10) % 10) + '0');
2194             rawdigits[p++] = (char) (((mant[i]) % 10) + '0');
2195         }
2196 
2197         // Find the first non-zero one
2198         for (p = 0; p < rawdigits.length; p++) {
2199             if (rawdigits[p] != '0') {
2200                 break;
2201             }
2202         }
2203         shf = p;
2204 
2205         // Now do the conversion
2206         q = 0;
2207         if (sign == -1) {
2208             outputbuffer[q++] = '-';
2209         }
2210 
2211         if (p != rawdigits.length) {
2212             // there are non zero digits...
2213             outputbuffer[q++] = rawdigits[p++];
2214             outputbuffer[q++] = '.';
2215 
2216             while (p < rawdigits.length) {
2217                 outputbuffer[q++] = rawdigits[p++];
2218             }
2219         } else {
2220             outputbuffer[q++] = '0';
2221             outputbuffer[q++] = '.';
2222             outputbuffer[q++] = '0';
2223             outputbuffer[q++] = 'e';
2224             outputbuffer[q++] = '0';
2225             return new String(outputbuffer, 0, 5);
2226         }
2227 
2228         outputbuffer[q++] = 'e';
2229 
2230         // Find the msd of the exponent
2231 
2232         e = exp * 4 - shf - 1;
2233         ae = e;
2234         if (e < 0) {
2235             ae = -e;
2236         }
2237 
2238         // Find the largest p such that p < e
2239         for (p = 1000000000; p > ae; p /= 10) {
2240             // nothing to do
2241         }
2242 
2243         if (e < 0) {
2244             outputbuffer[q++] = '-';
2245         }
2246 
2247         while (p > 0) {
2248             outputbuffer[q++] = (char) (ae / p + '0');
2249             ae %= p;
2250             p /= 10;
2251         }
2252 
2253         return new String(outputbuffer, 0, q);
2254     }
2255 
2256     /**
2257      * Convert an instance to a string using normal notation.
2258      *
2259      * @return string representation of the instance in normal notation
2260      */
dfp2string()2261     protected String dfp2string() {
2262         char buffer[] = new char[mant.length * 4 + 20];
2263         int p = 1;
2264         int q;
2265         int e = exp;
2266         boolean pointInserted = false;
2267 
2268         buffer[0] = ' ';
2269 
2270         if (e <= 0) {
2271             buffer[p++] = '0';
2272             buffer[p++] = '.';
2273             pointInserted = true;
2274         }
2275 
2276         while (e < 0) {
2277             buffer[p++] = '0';
2278             buffer[p++] = '0';
2279             buffer[p++] = '0';
2280             buffer[p++] = '0';
2281             e++;
2282         }
2283 
2284         for (int i = mant.length - 1; i >= 0; i--) {
2285             buffer[p++] = (char) ((mant[i] / 1000) + '0');
2286             buffer[p++] = (char) (((mant[i] / 100) % 10) + '0');
2287             buffer[p++] = (char) (((mant[i] / 10) % 10) + '0');
2288             buffer[p++] = (char) (((mant[i]) % 10) + '0');
2289             if (--e == 0) {
2290                 buffer[p++] = '.';
2291                 pointInserted = true;
2292             }
2293         }
2294 
2295         while (e > 0) {
2296             buffer[p++] = '0';
2297             buffer[p++] = '0';
2298             buffer[p++] = '0';
2299             buffer[p++] = '0';
2300             e--;
2301         }
2302 
2303         if (!pointInserted) {
2304             // Ensure we have a radix point!
2305             buffer[p++] = '.';
2306         }
2307 
2308         // Suppress leading zeros
2309         q = 1;
2310         while (buffer[q] == '0') {
2311             q++;
2312         }
2313         if (buffer[q] == '.') {
2314             q--;
2315         }
2316 
2317         // Suppress trailing zeros
2318         while (buffer[p - 1] == '0') {
2319             p--;
2320         }
2321 
2322         // Insert sign
2323         if (sign < 0) {
2324             buffer[--q] = '-';
2325         }
2326 
2327         return new String(buffer, q, p - q);
2328     }
2329 
2330     /**
2331      * Raises a trap. This does not set the corresponding flag however.
2332      *
2333      * @param type the trap type
2334      * @param what - name of routine trap occurred in
2335      * @param oper - input operator to function
2336      * @param result - the result computed prior to the trap
2337      * @return The suggested return value from the trap handler
2338      */
dotrap(int type, String what, Dfp oper, Dfp result)2339     public Dfp dotrap(int type, String what, Dfp oper, Dfp result) {
2340         Dfp def = result;
2341 
2342         switch (type) {
2343             case DfpField.FLAG_INVALID:
2344                 def = newInstance(getZero());
2345                 def.sign = result.sign;
2346                 def.nans = QNAN;
2347                 break;
2348 
2349             case DfpField.FLAG_DIV_ZERO:
2350                 if (nans == FINITE && mant[mant.length - 1] != 0) {
2351                     // normal case, we are finite, non-zero
2352                     def = newInstance(getZero());
2353                     def.sign = (byte) (sign * oper.sign);
2354                     def.nans = INFINITE;
2355                 }
2356 
2357                 if (nans == FINITE && mant[mant.length - 1] == 0) {
2358                     //  0/0
2359                     def = newInstance(getZero());
2360                     def.nans = QNAN;
2361                 }
2362 
2363                 if (nans == INFINITE || nans == QNAN) {
2364                     def = newInstance(getZero());
2365                     def.nans = QNAN;
2366                 }
2367 
2368                 if (nans == INFINITE || nans == SNAN) {
2369                     def = newInstance(getZero());
2370                     def.nans = QNAN;
2371                 }
2372                 break;
2373 
2374             case DfpField.FLAG_UNDERFLOW:
2375                 if ((result.exp + mant.length) < MIN_EXP) {
2376                     def = newInstance(getZero());
2377                     def.sign = result.sign;
2378                 } else {
2379                     def = newInstance(result); // gradual underflow
2380                 }
2381                 result.exp += ERR_SCALE;
2382                 break;
2383 
2384             case DfpField.FLAG_OVERFLOW:
2385                 result.exp -= ERR_SCALE;
2386                 def = newInstance(getZero());
2387                 def.sign = result.sign;
2388                 def.nans = INFINITE;
2389                 break;
2390 
2391             default:
2392                 def = result;
2393                 break;
2394         }
2395 
2396         return trap(type, what, oper, def, result);
2397     }
2398 
2399     /**
2400      * Trap handler. Subclasses may override this to provide trap functionality per IEEE 854-1987.
2401      *
2402      * @param type The exception type - e.g. FLAG_OVERFLOW
2403      * @param what The name of the routine we were in e.g. divide()
2404      * @param oper An operand to this function if any
2405      * @param def The default return value if trap not enabled
2406      * @param result The result that is specified to be delivered per IEEE 854, if any
2407      * @return the value that should be return by the operation triggering the trap
2408      */
trap(int type, String what, Dfp oper, Dfp def, Dfp result)2409     protected Dfp trap(int type, String what, Dfp oper, Dfp def, Dfp result) {
2410         return def;
2411     }
2412 
2413     /**
2414      * Returns the type - one of FINITE, INFINITE, SNAN, QNAN.
2415      *
2416      * @return type of the number
2417      */
classify()2418     public int classify() {
2419         return nans;
2420     }
2421 
2422     /**
2423      * Creates an instance that is the same as x except that it has the sign of y. abs(x) =
2424      * dfp.copysign(x, dfp.one)
2425      *
2426      * @param x number to get the value from
2427      * @param y number to get the sign from
2428      * @return a number with the value of x and the sign of y
2429      */
copysign(final Dfp x, final Dfp y)2430     public static Dfp copysign(final Dfp x, final Dfp y) {
2431         Dfp result = x.newInstance(x);
2432         result.sign = y.sign;
2433         return result;
2434     }
2435 
2436     /**
2437      * Returns the next number greater than this one in the direction of x. If this==x then simply
2438      * returns this.
2439      *
2440      * @param x direction where to look at
2441      * @return closest number next to instance in the direction of x
2442      */
nextAfter(final Dfp x)2443     public Dfp nextAfter(final Dfp x) {
2444 
2445         // make sure we don't mix number with different precision
2446         if (field.getRadixDigits() != x.field.getRadixDigits()) {
2447             field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
2448             final Dfp result = newInstance(getZero());
2449             result.nans = QNAN;
2450             return dotrap(DfpField.FLAG_INVALID, NEXT_AFTER_TRAP, x, result);
2451         }
2452 
2453         // if this is greater than x
2454         boolean up = false;
2455         if (this.lessThan(x)) {
2456             up = true;
2457         }
2458 
2459         if (compare(this, x) == 0) {
2460             return newInstance(x);
2461         }
2462 
2463         if (lessThan(getZero())) {
2464             up = !up;
2465         }
2466 
2467         final Dfp inc;
2468         Dfp result;
2469         if (up) {
2470             inc = newInstance(getOne());
2471             inc.exp = this.exp - mant.length + 1;
2472             inc.sign = this.sign;
2473 
2474             if (this.equals(getZero())) {
2475                 inc.exp = MIN_EXP - mant.length;
2476             }
2477 
2478             result = add(inc);
2479         } else {
2480             inc = newInstance(getOne());
2481             inc.exp = this.exp;
2482             inc.sign = this.sign;
2483 
2484             if (this.equals(inc)) {
2485                 inc.exp = this.exp - mant.length;
2486             } else {
2487                 inc.exp = this.exp - mant.length + 1;
2488             }
2489 
2490             if (this.equals(getZero())) {
2491                 inc.exp = MIN_EXP - mant.length;
2492             }
2493 
2494             result = this.subtract(inc);
2495         }
2496 
2497         if (result.classify() == INFINITE && this.classify() != INFINITE) {
2498             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
2499             result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result);
2500         }
2501 
2502         if (result.equals(getZero()) && this.equals(getZero()) == false) {
2503             field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
2504             result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result);
2505         }
2506 
2507         return result;
2508     }
2509 
2510     /**
2511      * Convert the instance into a double.
2512      *
2513      * @return a double approximating the instance
2514      * @see #toSplitDouble()
2515      */
toDouble()2516     public double toDouble() {
2517 
2518         if (isInfinite()) {
2519             if (lessThan(getZero())) {
2520                 return Double.NEGATIVE_INFINITY;
2521             } else {
2522                 return Double.POSITIVE_INFINITY;
2523             }
2524         }
2525 
2526         if (isNaN()) {
2527             return Double.NaN;
2528         }
2529 
2530         Dfp y = this;
2531         boolean negate = false;
2532         int cmp0 = compare(this, getZero());
2533         if (cmp0 == 0) {
2534             return sign < 0 ? -0.0 : +0.0;
2535         } else if (cmp0 < 0) {
2536             y = negate();
2537             negate = true;
2538         }
2539 
2540         /* Find the exponent, first estimate by integer log10, then adjust.
2541         Should be faster than doing a natural logarithm.  */
2542         int exponent = (int) (y.intLog10() * 3.32);
2543         if (exponent < 0) {
2544             exponent--;
2545         }
2546 
2547         Dfp tempDfp = DfpMath.pow(getTwo(), exponent);
2548         while (tempDfp.lessThan(y) || tempDfp.equals(y)) {
2549             tempDfp = tempDfp.multiply(2);
2550             exponent++;
2551         }
2552         exponent--;
2553 
2554         /* We have the exponent, now work on the mantissa */
2555 
2556         y = y.divide(DfpMath.pow(getTwo(), exponent));
2557         if (exponent > -1023) {
2558             y = y.subtract(getOne());
2559         }
2560 
2561         if (exponent < -1074) {
2562             return 0;
2563         }
2564 
2565         if (exponent > 1023) {
2566             return negate ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
2567         }
2568 
2569         y = y.multiply(newInstance(4503599627370496l)).rint();
2570         String str = y.toString();
2571         str = str.substring(0, str.length() - 1);
2572         long mantissa = Long.parseLong(str);
2573 
2574         if (mantissa == 4503599627370496L) {
2575             // Handle special case where we round up to next power of two
2576             mantissa = 0;
2577             exponent++;
2578         }
2579 
2580         /* Its going to be subnormal, so make adjustments */
2581         if (exponent <= -1023) {
2582             exponent--;
2583         }
2584 
2585         while (exponent < -1023) {
2586             exponent++;
2587             mantissa >>>= 1;
2588         }
2589 
2590         long bits = mantissa | ((exponent + 1023L) << 52);
2591         double x = Double.longBitsToDouble(bits);
2592 
2593         if (negate) {
2594             x = -x;
2595         }
2596 
2597         return x;
2598     }
2599 
2600     /**
2601      * Convert the instance into a split double.
2602      *
2603      * @return an array of two doubles which sum represent the instance
2604      * @see #toDouble()
2605      */
toSplitDouble()2606     public double[] toSplitDouble() {
2607         double split[] = new double[2];
2608         long mask = 0xffffffffc0000000L;
2609 
2610         split[0] = Double.longBitsToDouble(Double.doubleToLongBits(toDouble()) & mask);
2611         split[1] = subtract(newInstance(split[0])).toDouble();
2612 
2613         return split;
2614     }
2615 
2616     /**
2617      * {@inheritDoc}
2618      *
2619      * @since 3.2
2620      */
getReal()2621     public double getReal() {
2622         return toDouble();
2623     }
2624 
2625     /**
2626      * {@inheritDoc}
2627      *
2628      * @since 3.2
2629      */
add(final double a)2630     public Dfp add(final double a) {
2631         return add(newInstance(a));
2632     }
2633 
2634     /**
2635      * {@inheritDoc}
2636      *
2637      * @since 3.2
2638      */
subtract(final double a)2639     public Dfp subtract(final double a) {
2640         return subtract(newInstance(a));
2641     }
2642 
2643     /**
2644      * {@inheritDoc}
2645      *
2646      * @since 3.2
2647      */
multiply(final double a)2648     public Dfp multiply(final double a) {
2649         return multiply(newInstance(a));
2650     }
2651 
2652     /**
2653      * {@inheritDoc}
2654      *
2655      * @since 3.2
2656      */
divide(final double a)2657     public Dfp divide(final double a) {
2658         return divide(newInstance(a));
2659     }
2660 
2661     /**
2662      * {@inheritDoc}
2663      *
2664      * @since 3.2
2665      */
remainder(final double a)2666     public Dfp remainder(final double a) {
2667         return remainder(newInstance(a));
2668     }
2669 
2670     /**
2671      * {@inheritDoc}
2672      *
2673      * @since 3.2
2674      */
round()2675     public long round() {
2676         return FastMath.round(toDouble());
2677     }
2678 
2679     /**
2680      * {@inheritDoc}
2681      *
2682      * @since 3.2
2683      */
signum()2684     public Dfp signum() {
2685         if (isNaN() || isZero()) {
2686             return this;
2687         } else {
2688             return newInstance(sign > 0 ? +1 : -1);
2689         }
2690     }
2691 
2692     /**
2693      * {@inheritDoc}
2694      *
2695      * @since 3.2
2696      */
copySign(final Dfp s)2697     public Dfp copySign(final Dfp s) {
2698         if ((sign >= 0 && s.sign >= 0) || (sign < 0 && s.sign < 0)) { // Sign is currently OK
2699             return this;
2700         }
2701         return negate(); // flip sign
2702     }
2703 
2704     /**
2705      * {@inheritDoc}
2706      *
2707      * @since 3.2
2708      */
copySign(final double s)2709     public Dfp copySign(final double s) {
2710         long sb = Double.doubleToLongBits(s);
2711         if ((sign >= 0 && sb >= 0) || (sign < 0 && sb < 0)) { // Sign is currently OK
2712             return this;
2713         }
2714         return negate(); // flip sign
2715     }
2716 
2717     /**
2718      * {@inheritDoc}
2719      *
2720      * @since 3.2
2721      */
scalb(final int n)2722     public Dfp scalb(final int n) {
2723         return multiply(DfpMath.pow(getTwo(), n));
2724     }
2725 
2726     /**
2727      * {@inheritDoc}
2728      *
2729      * @since 3.2
2730      */
hypot(final Dfp y)2731     public Dfp hypot(final Dfp y) {
2732         return multiply(this).add(y.multiply(y)).sqrt();
2733     }
2734 
2735     /**
2736      * {@inheritDoc}
2737      *
2738      * @since 3.2
2739      */
cbrt()2740     public Dfp cbrt() {
2741         return rootN(3);
2742     }
2743 
2744     /**
2745      * {@inheritDoc}
2746      *
2747      * @since 3.2
2748      */
rootN(final int n)2749     public Dfp rootN(final int n) {
2750         return (sign >= 0)
2751                 ? DfpMath.pow(this, getOne().divide(n))
2752                 : DfpMath.pow(negate(), getOne().divide(n)).negate();
2753     }
2754 
2755     /**
2756      * {@inheritDoc}
2757      *
2758      * @since 3.2
2759      */
pow(final double p)2760     public Dfp pow(final double p) {
2761         return DfpMath.pow(this, newInstance(p));
2762     }
2763 
2764     /**
2765      * {@inheritDoc}
2766      *
2767      * @since 3.2
2768      */
pow(final int n)2769     public Dfp pow(final int n) {
2770         return DfpMath.pow(this, n);
2771     }
2772 
2773     /**
2774      * {@inheritDoc}
2775      *
2776      * @since 3.2
2777      */
pow(final Dfp e)2778     public Dfp pow(final Dfp e) {
2779         return DfpMath.pow(this, e);
2780     }
2781 
2782     /**
2783      * {@inheritDoc}
2784      *
2785      * @since 3.2
2786      */
exp()2787     public Dfp exp() {
2788         return DfpMath.exp(this);
2789     }
2790 
2791     /**
2792      * {@inheritDoc}
2793      *
2794      * @since 3.2
2795      */
expm1()2796     public Dfp expm1() {
2797         return DfpMath.exp(this).subtract(getOne());
2798     }
2799 
2800     /**
2801      * {@inheritDoc}
2802      *
2803      * @since 3.2
2804      */
log()2805     public Dfp log() {
2806         return DfpMath.log(this);
2807     }
2808 
2809     /**
2810      * {@inheritDoc}
2811      *
2812      * @since 3.2
2813      */
log1p()2814     public Dfp log1p() {
2815         return DfpMath.log(this.add(getOne()));
2816     }
2817 
2818     //  TODO: deactivate this implementation (and return type) in 4.0
2819     /**
2820      * Get the exponent of the greatest power of 10 that is less than or equal to abs(this).
2821      *
2822      * @return integer base 10 logarithm
2823      * @deprecated as of 3.2, replaced by {@link #intLog10()}, in 4.0 the return type will be
2824      *     changed to Dfp
2825      */
2826     @Deprecated
log10()2827     public int log10() {
2828         return intLog10();
2829     }
2830 
2831     //    TODO: activate this implementation (and return type) in 4.0
2832     //    /** {@inheritDoc}
2833     //     * @since 3.2
2834     //     */
2835     //    public Dfp log10() {
2836     //        return DfpMath.log(this).divide(DfpMath.log(newInstance(10)));
2837     //    }
2838 
2839     /**
2840      * {@inheritDoc}
2841      *
2842      * @since 3.2
2843      */
cos()2844     public Dfp cos() {
2845         return DfpMath.cos(this);
2846     }
2847 
2848     /**
2849      * {@inheritDoc}
2850      *
2851      * @since 3.2
2852      */
sin()2853     public Dfp sin() {
2854         return DfpMath.sin(this);
2855     }
2856 
2857     /**
2858      * {@inheritDoc}
2859      *
2860      * @since 3.2
2861      */
tan()2862     public Dfp tan() {
2863         return DfpMath.tan(this);
2864     }
2865 
2866     /**
2867      * {@inheritDoc}
2868      *
2869      * @since 3.2
2870      */
acos()2871     public Dfp acos() {
2872         return DfpMath.acos(this);
2873     }
2874 
2875     /**
2876      * {@inheritDoc}
2877      *
2878      * @since 3.2
2879      */
asin()2880     public Dfp asin() {
2881         return DfpMath.asin(this);
2882     }
2883 
2884     /**
2885      * {@inheritDoc}
2886      *
2887      * @since 3.2
2888      */
atan()2889     public Dfp atan() {
2890         return DfpMath.atan(this);
2891     }
2892 
2893     /**
2894      * {@inheritDoc}
2895      *
2896      * @since 3.2
2897      */
atan2(final Dfp x)2898     public Dfp atan2(final Dfp x) throws DimensionMismatchException {
2899 
2900         // compute r = sqrt(x^2+y^2)
2901         final Dfp r = x.multiply(x).add(multiply(this)).sqrt();
2902 
2903         if (x.sign >= 0) {
2904 
2905             // compute atan2(y, x) = 2 atan(y / (r + x))
2906             return getTwo().multiply(divide(r.add(x)).atan());
2907 
2908         } else {
2909 
2910             // compute atan2(y, x) = +/- pi - 2 atan(y / (r - x))
2911             final Dfp tmp = getTwo().multiply(divide(r.subtract(x)).atan());
2912             final Dfp pmPi = newInstance((tmp.sign <= 0) ? -FastMath.PI : FastMath.PI);
2913             return pmPi.subtract(tmp);
2914         }
2915     }
2916 
2917     /**
2918      * {@inheritDoc}
2919      *
2920      * @since 3.2
2921      */
cosh()2922     public Dfp cosh() {
2923         return DfpMath.exp(this).add(DfpMath.exp(negate())).divide(2);
2924     }
2925 
2926     /**
2927      * {@inheritDoc}
2928      *
2929      * @since 3.2
2930      */
sinh()2931     public Dfp sinh() {
2932         return DfpMath.exp(this).subtract(DfpMath.exp(negate())).divide(2);
2933     }
2934 
2935     /**
2936      * {@inheritDoc}
2937      *
2938      * @since 3.2
2939      */
tanh()2940     public Dfp tanh() {
2941         final Dfp ePlus = DfpMath.exp(this);
2942         final Dfp eMinus = DfpMath.exp(negate());
2943         return ePlus.subtract(eMinus).divide(ePlus.add(eMinus));
2944     }
2945 
2946     /**
2947      * {@inheritDoc}
2948      *
2949      * @since 3.2
2950      */
acosh()2951     public Dfp acosh() {
2952         return multiply(this).subtract(getOne()).sqrt().add(this).log();
2953     }
2954 
2955     /**
2956      * {@inheritDoc}
2957      *
2958      * @since 3.2
2959      */
asinh()2960     public Dfp asinh() {
2961         return multiply(this).add(getOne()).sqrt().add(this).log();
2962     }
2963 
2964     /**
2965      * {@inheritDoc}
2966      *
2967      * @since 3.2
2968      */
atanh()2969     public Dfp atanh() {
2970         return getOne().add(this).divide(getOne().subtract(this)).log().divide(2);
2971     }
2972 
2973     /**
2974      * {@inheritDoc}
2975      *
2976      * @since 3.2
2977      */
linearCombination(final Dfp[] a, final Dfp[] b)2978     public Dfp linearCombination(final Dfp[] a, final Dfp[] b) throws DimensionMismatchException {
2979         if (a.length != b.length) {
2980             throw new DimensionMismatchException(a.length, b.length);
2981         }
2982         Dfp r = getZero();
2983         for (int i = 0; i < a.length; ++i) {
2984             r = r.add(a[i].multiply(b[i]));
2985         }
2986         return r;
2987     }
2988 
2989     /**
2990      * {@inheritDoc}
2991      *
2992      * @since 3.2
2993      */
linearCombination(final double[] a, final Dfp[] b)2994     public Dfp linearCombination(final double[] a, final Dfp[] b)
2995             throws DimensionMismatchException {
2996         if (a.length != b.length) {
2997             throw new DimensionMismatchException(a.length, b.length);
2998         }
2999         Dfp r = getZero();
3000         for (int i = 0; i < a.length; ++i) {
3001             r = r.add(b[i].multiply(a[i]));
3002         }
3003         return r;
3004     }
3005 
3006     /**
3007      * {@inheritDoc}
3008      *
3009      * @since 3.2
3010      */
linearCombination(final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2)3011     public Dfp linearCombination(final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2) {
3012         return a1.multiply(b1).add(a2.multiply(b2));
3013     }
3014 
3015     /**
3016      * {@inheritDoc}
3017      *
3018      * @since 3.2
3019      */
linearCombination(final double a1, final Dfp b1, final double a2, final Dfp b2)3020     public Dfp linearCombination(final double a1, final Dfp b1, final double a2, final Dfp b2) {
3021         return b1.multiply(a1).add(b2.multiply(a2));
3022     }
3023 
3024     /**
3025      * {@inheritDoc}
3026      *
3027      * @since 3.2
3028      */
linearCombination( final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2, final Dfp a3, final Dfp b3)3029     public Dfp linearCombination(
3030             final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2, final Dfp a3, final Dfp b3) {
3031         return a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3));
3032     }
3033 
3034     /**
3035      * {@inheritDoc}
3036      *
3037      * @since 3.2
3038      */
linearCombination( final double a1, final Dfp b1, final double a2, final Dfp b2, final double a3, final Dfp b3)3039     public Dfp linearCombination(
3040             final double a1,
3041             final Dfp b1,
3042             final double a2,
3043             final Dfp b2,
3044             final double a3,
3045             final Dfp b3) {
3046         return b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3));
3047     }
3048 
3049     /**
3050      * {@inheritDoc}
3051      *
3052      * @since 3.2
3053      */
linearCombination( final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2, final Dfp a3, final Dfp b3, final Dfp a4, final Dfp b4)3054     public Dfp linearCombination(
3055             final Dfp a1,
3056             final Dfp b1,
3057             final Dfp a2,
3058             final Dfp b2,
3059             final Dfp a3,
3060             final Dfp b3,
3061             final Dfp a4,
3062             final Dfp b4) {
3063         return a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3)).add(a4.multiply(b4));
3064     }
3065 
3066     /**
3067      * {@inheritDoc}
3068      *
3069      * @since 3.2
3070      */
linearCombination( final double a1, final Dfp b1, final double a2, final Dfp b2, final double a3, final Dfp b3, final double a4, final Dfp b4)3071     public Dfp linearCombination(
3072             final double a1,
3073             final Dfp b1,
3074             final double a2,
3075             final Dfp b2,
3076             final double a3,
3077             final Dfp b3,
3078             final double a4,
3079             final Dfp b4) {
3080         return b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3)).add(b4.multiply(a4));
3081     }
3082 }
3083