1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/*
2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more
3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements.  See the NOTICE file distributed with
4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership.
5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0
6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with
7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License.  You may obtain a copy of the License at
8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *      http://www.apache.org/licenses/LICENSE-2.0
10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software
12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS,
13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and
15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License.
16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.dfp;
19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.Field;
21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** Field for Decimal floating point instances.
23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 995987 $ $Date: 2010-09-10 23:24:15 +0200 (ven. 10 sept. 2010) $
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class DfpField implements Field<Dfp> {
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Enumerate for rounding modes. */
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public enum RoundingMode {
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Rounds toward zero (truncation). */
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ROUND_DOWN,
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Rounds away from zero if discarded digit is non-zero. */
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ROUND_UP,
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Rounds towards nearest unless both are equidistant in which case it rounds away from zero. */
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ROUND_HALF_UP,
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Rounds towards nearest unless both are equidistant in which case it rounds toward zero. */
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ROUND_HALF_DOWN,
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Rounds towards nearest unless both are equidistant in which case it rounds toward the even neighbor.
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * This is the default as  specified by IEEE 854-1987
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         */
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ROUND_HALF_EVEN,
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Rounds towards nearest unless both are equidistant in which case it rounds toward the odd neighbor.  */
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ROUND_HALF_ODD,
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Rounds towards positive infinity. */
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ROUND_CEIL,
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Rounds towards negative infinity. */
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ROUND_FLOOR;
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** IEEE 854-1987 flag for invalid operation. */
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public static final int FLAG_INVALID   =  1;
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** IEEE 854-1987 flag for division by zero. */
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public static final int FLAG_DIV_ZERO  =  2;
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** IEEE 854-1987 flag for overflow. */
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public static final int FLAG_OVERFLOW  =  4;
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** IEEE 854-1987 flag for underflow. */
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public static final int FLAG_UNDERFLOW =  8;
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** IEEE 854-1987 flag for inexact result. */
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public static final int FLAG_INEXACT   = 16;
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of &radic;2. */
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String sqr2String;
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of &radic;2 / 2. */
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String sqr2ReciprocalString;
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of &radic;3. */
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String sqr3String;
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of &radic;3 / 3. */
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String sqr3ReciprocalString;
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of &pi;. */
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String piString;
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of e. */
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String eString;
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of ln(2). */
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String ln2String;
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of ln(5). */
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String ln5String;
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** High precision string representation of ln(10). */
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static String ln10String;
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** The number of radix digits.
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Note these depend on the radix which is 10000 digits,
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * so each one is equivalent to 4 decimal digits.
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final int radixDigits;
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value 0. */
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp zero;
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value 1. */
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp one;
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value 2. */
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp two;
115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value &radic;2. */
117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp sqr2;
118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A two elements {@link Dfp} array with value &radic;2 split in two pieces. */
120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp[] sqr2Split;
121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value &radic;2 / 2. */
123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp sqr2Reciprocal;
124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value &radic;3. */
126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp sqr3;
127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value &radic;3 / 3. */
129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp sqr3Reciprocal;
130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value &pi;. */
132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp pi;
133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A two elements {@link Dfp} array with value &pi; split in two pieces. */
135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp[] piSplit;
136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value e. */
138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp e;
139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A two elements {@link Dfp} array with value e split in two pieces. */
141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp[] eSplit;
142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value ln(2). */
144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp ln2;
145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A two elements {@link Dfp} array with value ln(2) split in two pieces. */
147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp[] ln2Split;
148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value ln(5). */
150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp ln5;
151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A two elements {@link Dfp} array with value ln(5) split in two pieces. */
153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp[] ln5Split;
154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** A {@link Dfp} with value ln(10). */
156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Dfp ln10;
157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Current rounding mode. */
159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private RoundingMode rMode;
160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** IEEE 854-1987 signals. */
162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private int ieeeFlags;
163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Create a factory for the specified number of radix digits.
165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Note that since the {@link Dfp} class uses 10000 as its radix, each radix
167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * digit is equivalent to 4 decimal digits. This implies that asking for
168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * 13, 14, 15 or 16 decimal digits will really lead to a 4 radix 10000 digits in
169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * all cases.
170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param decimalDigits minimal number of decimal digits.
172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public DfpField(final int decimalDigits) {
174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this(decimalDigits, true);
175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Create a factory for the specified number of radix digits.
178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Note that since the {@link Dfp} class uses 10000 as its radix, each radix
180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * digit is equivalent to 4 decimal digits. This implies that asking for
181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * 13, 14, 15 or 16 decimal digits will really lead to a 4 radix 10000 digits in
182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * all cases.
183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param decimalDigits minimal number of decimal digits
185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param computeConstants if true, the transcendental constants for the given precision
186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * must be computed (setting this flag to false is RESERVED for the internal recursive call)
187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private DfpField(final int decimalDigits, final boolean computeConstants) {
189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.radixDigits = (decimalDigits < 13) ? 4 : (decimalDigits + 3) / 4;
191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.rMode       = RoundingMode.ROUND_HALF_EVEN;
192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.ieeeFlags   = 0;
193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.zero        = new Dfp(this, 0);
194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.one         = new Dfp(this, 1);
195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.two         = new Dfp(this, 2);
196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (computeConstants) {
198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            // set up transcendental constants
199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            synchronized (DfpField.class) {
200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                // as a heuristic to circumvent Table-Maker's Dilemma, we set the string
202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                // representation of the constants to be at least 3 times larger than the
203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                // number of decimal digits, also as an attempt to really compute these
204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                // constants only once, we set a minimum number of digits
205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                computeStringConstants((decimalDigits < 67) ? 200 : (3 * decimalDigits));
206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                // set up the constants at current field accuracy
208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                sqr2           = new Dfp(this, sqr2String);
209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                sqr2Split      = split(sqr2String);
210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                sqr2Reciprocal = new Dfp(this, sqr2ReciprocalString);
211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                sqr3           = new Dfp(this, sqr3String);
212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                sqr3Reciprocal = new Dfp(this, sqr3ReciprocalString);
213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                pi             = new Dfp(this, piString);
214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                piSplit        = split(piString);
215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                e              = new Dfp(this, eString);
216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                eSplit         = split(eString);
217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                ln2            = new Dfp(this, ln2String);
218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                ln2Split       = split(ln2String);
219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                ln5            = new Dfp(this, ln5String);
220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                ln5Split       = split(ln5String);
221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                ln10           = new Dfp(this, ln10String);
222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else {
225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            // dummy settings for unused constants
226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr2           = null;
227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr2Split      = null;
228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr2Reciprocal = null;
229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr3           = null;
230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr3Reciprocal = null;
231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            pi             = null;
232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            piSplit        = null;
233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            e              = null;
234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            eSplit         = null;
235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ln2            = null;
236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ln2Split       = null;
237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ln5            = null;
238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ln5Split       = null;
239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ln10           = null;
240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the number of radix digits of the {@link Dfp} instances built by this factory.
245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return number of radix digits
246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public int getRadixDigits() {
248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return radixDigits;
249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Set the rounding mode.
252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  If not set, the default value is {@link RoundingMode#ROUND_HALF_EVEN}.
253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param mode desired rounding mode
254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Note that the rounding mode is common to all {@link Dfp} instances
255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * belonging to the current {@link DfpField} in the system and will
256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * affect all future calculations.
257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setRoundingMode(final RoundingMode mode) {
259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        rMode = mode;
260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the current rounding mode.
263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return current rounding mode
264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public RoundingMode getRoundingMode() {
266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return rMode;
267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the IEEE 854 status flags.
270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return IEEE 854 status flags
271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #clearIEEEFlags()
272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #setIEEEFlags(int)
273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #setIEEEFlagsBits(int)
274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_INVALID
275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_DIV_ZERO
276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_OVERFLOW
277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_UNDERFLOW
278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_INEXACT
279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public int getIEEEFlags() {
281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return ieeeFlags;
282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Clears the IEEE 854 status flags.
285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #getIEEEFlags()
286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #setIEEEFlags(int)
287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #setIEEEFlagsBits(int)
288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_INVALID
289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_DIV_ZERO
290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_OVERFLOW
291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_UNDERFLOW
292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_INEXACT
293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void clearIEEEFlags() {
295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ieeeFlags = 0;
296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Sets the IEEE 854 status flags.
299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param flags desired value for the flags
300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #getIEEEFlags()
301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #clearIEEEFlags()
302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #setIEEEFlagsBits(int)
303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_INVALID
304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_DIV_ZERO
305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_OVERFLOW
306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_UNDERFLOW
307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_INEXACT
308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setIEEEFlags(final int flags) {
310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ieeeFlags = flags & (FLAG_INVALID | FLAG_DIV_ZERO | FLAG_OVERFLOW | FLAG_UNDERFLOW | FLAG_INEXACT);
311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Sets some bits in the IEEE 854 status flags, without changing the already set bits.
314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Calling this method is equivalent to call {@code setIEEEFlags(getIEEEFlags() | bits)}
316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param bits bits to set
318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #getIEEEFlags()
319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #clearIEEEFlags()
320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #setIEEEFlags(int)
321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_INVALID
322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_DIV_ZERO
323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_OVERFLOW
324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_UNDERFLOW
325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #FLAG_INEXACT
326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setIEEEFlagsBits(final int bits) {
328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ieeeFlags |= bits & (FLAG_INVALID | FLAG_DIV_ZERO | FLAG_OVERFLOW | FLAG_UNDERFLOW | FLAG_INEXACT);
329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Makes a {@link Dfp} with a value of 0.
332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new {@link Dfp} with a value of 0
333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp newDfp() {
335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new Dfp(this);
336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Create an instance from a byte value.
339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param x value to convert to an instance
340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new {@link Dfp} with the same value as x
341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp newDfp(final byte x) {
343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new Dfp(this, x);
344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Create an instance from an int value.
347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param x value to convert to an instance
348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new {@link Dfp} with the same value as x
349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp newDfp(final int x) {
351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new Dfp(this, x);
352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Create an instance from a long value.
355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param x value to convert to an instance
356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new {@link Dfp} with the same value as x
357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp newDfp(final long x) {
359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new Dfp(this, x);
360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Create an instance from a double value.
363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param x value to convert to an instance
364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new {@link Dfp} with the same value as x
365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp newDfp(final double x) {
367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new Dfp(this, x);
368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Copy constructor.
371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param d instance to copy
372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new {@link Dfp} with the same value as d
373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp newDfp(Dfp d) {
375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new Dfp(d);
376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Create a {@link Dfp} given a String representation.
379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param s string representation of the instance
380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new {@link Dfp} parsed from specified string
381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp newDfp(final String s) {
383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new Dfp(this, s);
384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Creates a {@link Dfp} with a non-finite value.
387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param sign sign of the Dfp to create
388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param nans code of the value, must be one of {@link Dfp#INFINITE},
389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * {@link Dfp#SNAN},  {@link Dfp#QNAN}
390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new {@link Dfp} with a non-finite value
391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp newDfp(final byte sign, final byte nans) {
393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new Dfp(this, sign, nans);
394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant 0.
397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value 0
398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getZero() {
400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return zero;
401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant 1.
404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value 1
405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getOne() {
407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return one;
408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant 2.
411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value 2
412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getTwo() {
414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return two;
415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant &radic;2.
418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value &radic;2
419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getSqr2() {
421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return sqr2;
422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant &radic;2 split in two pieces.
425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value &radic;2 split in two pieces
426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp[] getSqr2Split() {
428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return sqr2Split.clone();
429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant &radic;2 / 2.
432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value &radic;2 / 2
433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getSqr2Reciprocal() {
435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return sqr2Reciprocal;
436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant &radic;3.
439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value &radic;3
440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getSqr3() {
442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return sqr3;
443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant &radic;3 / 3.
446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value &radic;3 / 3
447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getSqr3Reciprocal() {
449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return sqr3Reciprocal;
450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant &pi;.
453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value &pi;
454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getPi() {
456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return pi;
457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant &pi; split in two pieces.
460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value &pi; split in two pieces
461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp[] getPiSplit() {
463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return piSplit.clone();
464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant e.
467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value e
468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getE() {
470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return e;
471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant e split in two pieces.
474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value e split in two pieces
475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp[] getESplit() {
477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return eSplit.clone();
478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant ln(2).
481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value ln(2)
482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getLn2() {
484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return ln2;
485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant ln(2) split in two pieces.
488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value ln(2) split in two pieces
489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp[] getLn2Split() {
491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return ln2Split.clone();
492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant ln(5).
495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value ln(5)
496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getLn5() {
498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return ln5;
499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant ln(5) split in two pieces.
502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value ln(5) split in two pieces
503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp[] getLn5Split() {
505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return ln5Split.clone();
506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Get the constant ln(10).
509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a {@link Dfp} with value ln(10)
510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Dfp getLn10() {
512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return ln10;
513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Breaks a string representation up into two {@link Dfp}'s.
516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * The split is such that the sum of them is equivalent to the input string,
517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * but has higher precision than using a single Dfp.
518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param a string representation of the number to split
519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return an array of two {@link Dfp Dfp} instances which sum equals a
520dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
521dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private Dfp[] split(final String a) {
522dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      Dfp result[] = new Dfp[2];
523dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      boolean leading = true;
524dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      int sp = 0;
525dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      int sig = 0;
526dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
527dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      char[] buf = new char[a.length()];
528dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
529dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      for (int i = 0; i < buf.length; i++) {
530dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        buf[i] = a.charAt(i);
531dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
532dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (buf[i] >= '1' && buf[i] <= '9') {
533dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            leading = false;
534dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
535dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
536dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (buf[i] == '.') {
537dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          sig += (400 - sig) % 4;
538dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          leading = false;
539dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
540dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
541dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (sig == (radixDigits / 2) * 4) {
542dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          sp = i;
543dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          break;
544dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
545dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
546dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (buf[i] >= '0' && buf[i] <= '9' && !leading) {
547dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sig ++;
548dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
549dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
550dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
551dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      result[0] = new Dfp(this, new String(buf, 0, sp));
552dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
553dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      for (int i = 0; i < buf.length; i++) {
554dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        buf[i] = a.charAt(i);
555dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (buf[i] >= '0' && buf[i] <= '9' && i < sp) {
556dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            buf[i] = '0';
557dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
558dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
559dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
560dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      result[1] = new Dfp(this, new String(buf));
561dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
562dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      return result;
563dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
564dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
565dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
566dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Recompute the high precision string constants.
567dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param highPrecisionDecimalDigits precision at which the string constants mus be computed
568dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
569dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static void computeStringConstants(final int highPrecisionDecimalDigits) {
570dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (sqr2String == null || sqr2String.length() < highPrecisionDecimalDigits - 3) {
571dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
572dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            // recompute the string representation of the transcendental constants
573dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final DfpField highPrecisionField = new DfpField(highPrecisionDecimalDigits, false);
574dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp highPrecisionOne        = new Dfp(highPrecisionField, 1);
575dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp highPrecisionTwo        = new Dfp(highPrecisionField, 2);
576dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp highPrecisionThree      = new Dfp(highPrecisionField, 3);
577dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
578dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp highPrecisionSqr2 = highPrecisionTwo.sqrt();
579dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr2String           = highPrecisionSqr2.toString();
580dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr2ReciprocalString = highPrecisionOne.divide(highPrecisionSqr2).toString();
581dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
582dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp highPrecisionSqr3 = highPrecisionThree.sqrt();
583dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr3String           = highPrecisionSqr3.toString();
584dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            sqr3ReciprocalString = highPrecisionOne.divide(highPrecisionSqr3).toString();
585dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
586dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            piString   = computePi(highPrecisionOne, highPrecisionTwo, highPrecisionThree).toString();
587dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            eString    = computeExp(highPrecisionOne, highPrecisionOne).toString();
588dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ln2String  = computeLn(highPrecisionTwo, highPrecisionOne, highPrecisionTwo).toString();
589dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ln5String  = computeLn(new Dfp(highPrecisionField, 5),  highPrecisionOne, highPrecisionTwo).toString();
590dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ln10String = computeLn(new Dfp(highPrecisionField, 10), highPrecisionOne, highPrecisionTwo).toString();
591dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
592dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
593dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
594dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
595dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Compute &pi; using Jonathan and Peter Borwein quartic formula.
596dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param one constant with value 1 at desired precision
597dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param two constant with value 2 at desired precision
598dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param three constant with value 3 at desired precision
599dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return &pi;
600dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
601dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static Dfp computePi(final Dfp one, final Dfp two, final Dfp three) {
602dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
603dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp sqrt2   = two.sqrt();
604dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp yk      = sqrt2.subtract(one);
605dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp four    = two.add(two);
606dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp two2kp3 = two;
607dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp ak      = two.multiply(three.subtract(two.multiply(sqrt2)));
608dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
609dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // The formula converges quartically. This means the number of correct
610dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // digits is multiplied by 4 at each iteration! Five iterations are
611dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // sufficient for about 160 digits, eight iterations give about
612dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // 10000 digits (this has been checked) and 20 iterations more than
613dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // 160 billions of digits (this has NOT been checked).
614dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // So the limit here is considered sufficient for most purposes ...
615dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 1; i < 20; i++) {
616dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp ykM1 = yk;
617dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
618dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp y2         = yk.multiply(yk);
619dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp oneMinusY4 = one.subtract(y2.multiply(y2));
620dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp s          = oneMinusY4.sqrt().sqrt();
621dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            yk = one.subtract(s).divide(one.add(s));
622dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
623dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            two2kp3 = two2kp3.multiply(four);
624dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
625dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp p = one.add(yk);
626dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final Dfp p2 = p.multiply(p);
627dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ak = ak.multiply(p2.multiply(p2)).subtract(two2kp3.multiply(yk).multiply(one.add(yk).add(yk.multiply(yk))));
628dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
629dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (yk.equals(ykM1)) {
630dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                break;
631dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
632dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
633dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
634dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return one.divide(ak);
635dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
636dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
637dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
638dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Compute exp(a).
639dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param a number for which we want the exponential
640dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param one constant with value 1 at desired precision
641dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return exp(a)
642dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
643dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public static Dfp computeExp(final Dfp a, final Dfp one) {
644dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
645dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp y  = new Dfp(one);
646dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp py = new Dfp(one);
647dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp f  = new Dfp(one);
648dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp fi = new Dfp(one);
649dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp x  = new Dfp(one);
650dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
651dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < 10000; i++) {
652dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            x = x.multiply(a);
653dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            y = y.add(x.divide(f));
654dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            fi = fi.add(one);
655dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            f = f.multiply(fi);
656dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (y.equals(py)) {
657dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                break;
658dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
659dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            py = new Dfp(y);
660dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
661dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
662dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return y;
663dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
664dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
665dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
666dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
667dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Compute ln(a).
668dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
669dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  Let f(x) = ln(x),
670dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
671dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  We know that f'(x) = 1/x, thus from Taylor's theorem we have:
672dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
673dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *           -----          n+1         n
674dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  f(x) =   \           (-1)    (x - 1)
675dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *           /          ----------------    for 1 <= n <= infinity
676dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *           -----             n
677dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
678dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  or
679dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                       2        3       4
680dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                   (x-1)   (x-1)    (x-1)
681dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  ln(x) =  (x-1) - ----- + ------ - ------ + ...
682dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                     2       3        4
683dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
684dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  alternatively,
685dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
686dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                  2    3   4
687dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                 x    x   x
688dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  ln(x+1) =  x - -  + - - - + ...
689dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                 2    3   4
690dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
691dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  This series can be used to compute ln(x), but it converges too slowly.
692dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
693dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  If we substitute -x for x above, we get
694dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
695dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                   2    3    4
696dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                  x    x    x
697dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  ln(1-x) =  -x - -  - -  - - + ...
698dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                  2    3    4
699dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
700dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  Note that all terms are now negative.  Because the even powered ones
701dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  absorbed the sign.  Now, subtract the series above from the previous
702dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  one to get ln(x+1) - ln(1-x).  Note the even terms cancel out leaving
703dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  only the odd ones
704dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
705dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                             3     5      7
706dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                           2x    2x     2x
707dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  ln(x+1) - ln(x-1) = 2x + --- + --- + ---- + ...
708dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                            3     5      7
709dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
710dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  By the property of logarithms that ln(a) - ln(b) = ln (a/b) we have:
711dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
712dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                                3        5        7
713dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *      x+1           /          x        x        x          \
714dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  ln ----- =   2 *  |  x  +   ----  +  ----  +  ---- + ...  |
715dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *      x-1           \          3        5        7          /
716dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
717dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  But now we want to find ln(a), so we need to find the value of x
718dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  such that a = (x+1)/(x-1).   This is easily solved to find that
719dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *  x = (a-1)/(a+1).
720dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param a number for which we want the exponential
721dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param one constant with value 1 at desired precision
722dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param two constant with value 2 at desired precision
723dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return ln(a)
724dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
725dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
726dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public static Dfp computeLn(final Dfp a, final Dfp one, final Dfp two) {
727dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
728dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        int den = 1;
729dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp x = a.add(new Dfp(a.getField(), -1)).divide(a.add(one));
730dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
731dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp y = new Dfp(x);
732dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp num = new Dfp(x);
733dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Dfp py = new Dfp(y);
734dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < 10000; i++) {
735dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            num = num.multiply(x);
736dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            num = num.multiply(x);
737dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            den = den + 2;
738dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            Dfp t = num.divide(den);
739dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            y = y.add(t);
740dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (y.equals(py)) {
741dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                break;
742dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
743dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            py = new Dfp(y);
744dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
745dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
746dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return y.multiply(two);
747dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
748dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
749dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
750dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond}
751