DfpField.java

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

  17. package org.apache.commons.math4.legacy.core.dfp;

  18. import org.apache.commons.math4.legacy.core.Field;
  19. import org.apache.commons.math4.legacy.core.FieldElement;

  20. /** Field for Decimal floating point instances.
  21.  * @since 2.2
  22.  */
  23. public class DfpField implements Field<Dfp> {

  24.     /** Enumerate for rounding modes. */
  25.     public enum RoundingMode {

  26.         /** Rounds toward zero (truncation). */
  27.         ROUND_DOWN,

  28.         /** Rounds away from zero if discarded digit is non-zero. */
  29.         ROUND_UP,

  30.         /** Rounds towards nearest unless both are equidistant in which case it rounds away from zero. */
  31.         ROUND_HALF_UP,

  32.         /** Rounds towards nearest unless both are equidistant in which case it rounds toward zero. */
  33.         ROUND_HALF_DOWN,

  34.         /** Rounds towards nearest unless both are equidistant in which case it rounds toward the even neighbor.
  35.          * This is the default as  specified by IEEE 854-1987
  36.          */
  37.         ROUND_HALF_EVEN,

  38.         /** Rounds towards nearest unless both are equidistant in which case it rounds toward the odd neighbor.  */
  39.         ROUND_HALF_ODD,

  40.         /** Rounds towards positive infinity. */
  41.         ROUND_CEIL,

  42.         /** Rounds towards negative infinity. */
  43.         ROUND_FLOOR;
  44.     }

  45.     /** IEEE 854-1987 flag for invalid operation. */
  46.     public static final int FLAG_INVALID   =  1;

  47.     /** IEEE 854-1987 flag for division by zero. */
  48.     public static final int FLAG_DIV_ZERO  =  2;

  49.     /** IEEE 854-1987 flag for overflow. */
  50.     public static final int FLAG_OVERFLOW  =  4;

  51.     /** IEEE 854-1987 flag for underflow. */
  52.     public static final int FLAG_UNDERFLOW =  8;

  53.     /** IEEE 854-1987 flag for inexact result. */
  54.     public static final int FLAG_INEXACT   = 16;

  55.     /** High precision string representation of &radic;2. */
  56.     private static String sqr2String;

  57.     // Note: the static strings are set up (once) by the ctor and @GuardedBy("DfpField.class")

  58.     /** High precision string representation of &radic;2 / 2. */
  59.     private static String sqr2ReciprocalString;

  60.     /** High precision string representation of &radic;3. */
  61.     private static String sqr3String;

  62.     /** High precision string representation of &radic;3 / 3. */
  63.     private static String sqr3ReciprocalString;

  64.     /** High precision string representation of &pi;. */
  65.     private static String piString;

  66.     /** High precision string representation of e. */
  67.     private static String eString;

  68.     /** High precision string representation of ln(2). */
  69.     private static String ln2String;

  70.     /** High precision string representation of ln(5). */
  71.     private static String ln5String;

  72.     /** High precision string representation of ln(10). */
  73.     private static String ln10String;

  74.     /** The number of radix digits.
  75.      * Note these depend on the radix which is 10000 digits,
  76.      * so each one is equivalent to 4 decimal digits.
  77.      */
  78.     private final int radixDigits;

  79.     /** A {@link Dfp} with value 0. */
  80.     private final Dfp zero;

  81.     /** A {@link Dfp} with value 1. */
  82.     private final Dfp one;

  83.     /** A {@link Dfp} with value 2. */
  84.     private final Dfp two;

  85.     /** A {@link Dfp} with value &radic;2. */
  86.     private final Dfp sqr2;

  87.     /** A two elements {@link Dfp} array with value &radic;2 split in two pieces. */
  88.     private final Dfp[] sqr2Split;

  89.     /** A {@link Dfp} with value &radic;2 / 2. */
  90.     private final Dfp sqr2Reciprocal;

  91.     /** A {@link Dfp} with value &radic;3. */
  92.     private final Dfp sqr3;

  93.     /** A {@link Dfp} with value &radic;3 / 3. */
  94.     private final Dfp sqr3Reciprocal;

  95.     /** A {@link Dfp} with value &pi;. */
  96.     private final Dfp pi;

  97.     /** A two elements {@link Dfp} array with value &pi; split in two pieces. */
  98.     private final Dfp[] piSplit;

  99.     /** A {@link Dfp} with value e. */
  100.     private final Dfp e;

  101.     /** A two elements {@link Dfp} array with value e split in two pieces. */
  102.     private final Dfp[] eSplit;

  103.     /** A {@link Dfp} with value ln(2). */
  104.     private final Dfp ln2;

  105.     /** A two elements {@link Dfp} array with value ln(2) split in two pieces. */
  106.     private final Dfp[] ln2Split;

  107.     /** A {@link Dfp} with value ln(5). */
  108.     private final Dfp ln5;

  109.     /** A two elements {@link Dfp} array with value ln(5) split in two pieces. */
  110.     private final Dfp[] ln5Split;

  111.     /** A {@link Dfp} with value ln(10). */
  112.     private final Dfp ln10;

  113.     /** Current rounding mode. */
  114.     private RoundingMode rMode;

  115.     /** IEEE 854-1987 signals. */
  116.     private int ieeeFlags;

  117.     /** Create a factory for the specified number of radix digits.
  118.      * <p>
  119.      * Note that since the {@link Dfp} class uses 10000 as its radix, each radix
  120.      * digit is equivalent to 4 decimal digits. This implies that asking for
  121.      * 13, 14, 15 or 16 decimal digits will really lead to a 4 radix 10000 digits in
  122.      * all cases.
  123.      * </p>
  124.      * @param decimalDigits minimal number of decimal digits.
  125.      */
  126.     public DfpField(final int decimalDigits) {
  127.         this(decimalDigits, true);
  128.     }

  129.     /** Create a factory for the specified number of radix digits.
  130.      * <p>
  131.      * Note that since the {@link Dfp} class uses 10000 as its radix, each radix
  132.      * digit is equivalent to 4 decimal digits. This implies that asking for
  133.      * 13, 14, 15 or 16 decimal digits will really lead to a 4 radix 10000 digits in
  134.      * all cases.
  135.      * </p>
  136.      * @param decimalDigits minimal number of decimal digits
  137.      * @param computeConstants if true, the transcendental constants for the given precision
  138.      * must be computed (setting this flag to false is RESERVED for the internal recursive call)
  139.      */
  140.     private DfpField(final int decimalDigits, final boolean computeConstants) {

  141.         this.radixDigits = (decimalDigits < 13) ? 4 : (decimalDigits + 3) / 4;
  142.         this.rMode       = RoundingMode.ROUND_HALF_EVEN;
  143.         this.ieeeFlags   = 0;
  144.         this.zero        = new Dfp(this, 0);
  145.         this.one         = new Dfp(this, 1);
  146.         this.two         = new Dfp(this, 2);

  147.         if (computeConstants) {
  148.             // set up transcendental constants
  149.             synchronized (DfpField.class) {

  150.                 // as a heuristic to circumvent Table-Maker's Dilemma, we set the string
  151.                 // representation of the constants to be at least 3 times larger than the
  152.                 // number of decimal digits, also as an attempt to really compute these
  153.                 // constants only once, we set a minimum number of digits
  154.                 computeStringConstants((decimalDigits < 67) ? 200 : (3 * decimalDigits));

  155.                 // set up the constants at current field accuracy
  156.                 sqr2           = new Dfp(this, sqr2String);
  157.                 sqr2Split      = split(sqr2String);
  158.                 sqr2Reciprocal = new Dfp(this, sqr2ReciprocalString);
  159.                 sqr3           = new Dfp(this, sqr3String);
  160.                 sqr3Reciprocal = new Dfp(this, sqr3ReciprocalString);
  161.                 pi             = new Dfp(this, piString);
  162.                 piSplit        = split(piString);
  163.                 e              = new Dfp(this, eString);
  164.                 eSplit         = split(eString);
  165.                 ln2            = new Dfp(this, ln2String);
  166.                 ln2Split       = split(ln2String);
  167.                 ln5            = new Dfp(this, ln5String);
  168.                 ln5Split       = split(ln5String);
  169.                 ln10           = new Dfp(this, ln10String);
  170.             }
  171.         } else {
  172.             // dummy settings for unused constants
  173.             sqr2           = null;
  174.             sqr2Split      = null;
  175.             sqr2Reciprocal = null;
  176.             sqr3           = null;
  177.             sqr3Reciprocal = null;
  178.             pi             = null;
  179.             piSplit        = null;
  180.             e              = null;
  181.             eSplit         = null;
  182.             ln2            = null;
  183.             ln2Split       = null;
  184.             ln5            = null;
  185.             ln5Split       = null;
  186.             ln10           = null;
  187.         }
  188.     }

  189.     /** Get the number of radix digits of the {@link Dfp} instances built by this factory.
  190.      * @return number of radix digits
  191.      */
  192.     public int getRadixDigits() {
  193.         return radixDigits;
  194.     }

  195.     /** Set the rounding mode.
  196.      *  If not set, the default value is {@link RoundingMode#ROUND_HALF_EVEN}.
  197.      * @param mode desired rounding mode
  198.      * Note that the rounding mode is common to all {@link Dfp} instances
  199.      * belonging to the current {@link DfpField} in the system and will
  200.      * affect all future calculations.
  201.      */
  202.     public void setRoundingMode(final RoundingMode mode) {
  203.         rMode = mode;
  204.     }

  205.     /** Get the current rounding mode.
  206.      * @return current rounding mode
  207.      */
  208.     public RoundingMode getRoundingMode() {
  209.         return rMode;
  210.     }

  211.     /** Get the IEEE 854 status flags.
  212.      * @return IEEE 854 status flags
  213.      * @see #clearIEEEFlags()
  214.      * @see #setIEEEFlags(int)
  215.      * @see #setIEEEFlagsBits(int)
  216.      * @see #FLAG_INVALID
  217.      * @see #FLAG_DIV_ZERO
  218.      * @see #FLAG_OVERFLOW
  219.      * @see #FLAG_UNDERFLOW
  220.      * @see #FLAG_INEXACT
  221.      */
  222.     public int getIEEEFlags() {
  223.         return ieeeFlags;
  224.     }

  225.     /** Clears the IEEE 854 status flags.
  226.      * @see #getIEEEFlags()
  227.      * @see #setIEEEFlags(int)
  228.      * @see #setIEEEFlagsBits(int)
  229.      * @see #FLAG_INVALID
  230.      * @see #FLAG_DIV_ZERO
  231.      * @see #FLAG_OVERFLOW
  232.      * @see #FLAG_UNDERFLOW
  233.      * @see #FLAG_INEXACT
  234.      */
  235.     public void clearIEEEFlags() {
  236.         ieeeFlags = 0;
  237.     }

  238.     /** Sets the IEEE 854 status flags.
  239.      * @param flags desired value for the flags
  240.      * @see #getIEEEFlags()
  241.      * @see #clearIEEEFlags()
  242.      * @see #setIEEEFlagsBits(int)
  243.      * @see #FLAG_INVALID
  244.      * @see #FLAG_DIV_ZERO
  245.      * @see #FLAG_OVERFLOW
  246.      * @see #FLAG_UNDERFLOW
  247.      * @see #FLAG_INEXACT
  248.      */
  249.     public void setIEEEFlags(final int flags) {
  250.         ieeeFlags = flags & (FLAG_INVALID | FLAG_DIV_ZERO | FLAG_OVERFLOW | FLAG_UNDERFLOW | FLAG_INEXACT);
  251.     }

  252.     /** Sets some bits in the IEEE 854 status flags, without changing the already set bits.
  253.      * <p>
  254.      * Calling this method is equivalent to call {@code setIEEEFlags(getIEEEFlags() | bits)}
  255.      * </p>
  256.      * @param bits bits to set
  257.      * @see #getIEEEFlags()
  258.      * @see #clearIEEEFlags()
  259.      * @see #setIEEEFlags(int)
  260.      * @see #FLAG_INVALID
  261.      * @see #FLAG_DIV_ZERO
  262.      * @see #FLAG_OVERFLOW
  263.      * @see #FLAG_UNDERFLOW
  264.      * @see #FLAG_INEXACT
  265.      */
  266.     public void setIEEEFlagsBits(final int bits) {
  267.         ieeeFlags |= bits & (FLAG_INVALID | FLAG_DIV_ZERO | FLAG_OVERFLOW | FLAG_UNDERFLOW | FLAG_INEXACT);
  268.     }

  269.     /** Makes a {@link Dfp} with a value of 0.
  270.      * @return a new {@link Dfp} with a value of 0
  271.      */
  272.     public Dfp newDfp() {
  273.         return new Dfp(this);
  274.     }

  275.     /** Create an instance from a byte value.
  276.      * @param x value to convert to an instance
  277.      * @return a new {@link Dfp} with the same value as x
  278.      */
  279.     public Dfp newDfp(final byte x) {
  280.         return new Dfp(this, x);
  281.     }

  282.     /** Create an instance from an int value.
  283.      * @param x value to convert to an instance
  284.      * @return a new {@link Dfp} with the same value as x
  285.      */
  286.     public Dfp newDfp(final int x) {
  287.         return new Dfp(this, x);
  288.     }

  289.     /** Create an instance from a long value.
  290.      * @param x value to convert to an instance
  291.      * @return a new {@link Dfp} with the same value as x
  292.      */
  293.     public Dfp newDfp(final long x) {
  294.         return new Dfp(this, x);
  295.     }

  296.     /** Create an instance from a double value.
  297.      * @param x value to convert to an instance
  298.      * @return a new {@link Dfp} with the same value as x
  299.      */
  300.     public Dfp newDfp(final double x) {
  301.         return new Dfp(this, x);
  302.     }

  303.     /** Copy constructor.
  304.      * @param d instance to copy
  305.      * @return a new {@link Dfp} with the same value as d
  306.      */
  307.     public Dfp newDfp(Dfp d) {
  308.         return new Dfp(d);
  309.     }

  310.     /** Create a {@link Dfp} given a String representation.
  311.      * @param s string representation of the instance
  312.      * @return a new {@link Dfp} parsed from specified string
  313.      */
  314.     public Dfp newDfp(final String s) {
  315.         return new Dfp(this, s);
  316.     }

  317.     /** Creates a {@link Dfp} with a non-finite value.
  318.      * @param sign sign of the Dfp to create
  319.      * @param nans code of the value, must be one of {@link Dfp#INFINITE},
  320.      * {@link Dfp#SNAN},  {@link Dfp#QNAN}
  321.      * @return a new {@link Dfp} with a non-finite value
  322.      */
  323.     public Dfp newDfp(final byte sign, final byte nans) {
  324.         return new Dfp(this, sign, nans);
  325.     }

  326.     /** Get the constant 0.
  327.      * @return a {@link Dfp} with value 0
  328.      */
  329.     @Override
  330.     public Dfp getZero() {
  331.         return zero;
  332.     }

  333.     /** Get the constant 1.
  334.      * @return a {@link Dfp} with value 1
  335.      */
  336.     @Override
  337.     public Dfp getOne() {
  338.         return one;
  339.     }

  340.     /** {@inheritDoc} */
  341.     @Override
  342.     public Class<? extends FieldElement<Dfp>> getRuntimeClass() {
  343.         return Dfp.class;
  344.     }

  345.     /** Get the constant 2.
  346.      * @return a {@link Dfp} with value 2
  347.      */
  348.     public Dfp getTwo() {
  349.         return two;
  350.     }

  351.     /** Get the constant &radic;2.
  352.      * @return a {@link Dfp} with value &radic;2
  353.      */
  354.     public Dfp getSqr2() {
  355.         return sqr2;
  356.     }

  357.     /** Get the constant &radic;2 split in two pieces.
  358.      * @return a {@link Dfp} with value &radic;2 split in two pieces
  359.      */
  360.     public Dfp[] getSqr2Split() {
  361.         return sqr2Split.clone();
  362.     }

  363.     /** Get the constant &radic;2 / 2.
  364.      * @return a {@link Dfp} with value &radic;2 / 2
  365.      */
  366.     public Dfp getSqr2Reciprocal() {
  367.         return sqr2Reciprocal;
  368.     }

  369.     /** Get the constant &radic;3.
  370.      * @return a {@link Dfp} with value &radic;3
  371.      */
  372.     public Dfp getSqr3() {
  373.         return sqr3;
  374.     }

  375.     /** Get the constant &radic;3 / 3.
  376.      * @return a {@link Dfp} with value &radic;3 / 3
  377.      */
  378.     public Dfp getSqr3Reciprocal() {
  379.         return sqr3Reciprocal;
  380.     }

  381.     /** Get the constant &pi;.
  382.      * @return a {@link Dfp} with value &pi;
  383.      */
  384.     public Dfp getPi() {
  385.         return pi;
  386.     }

  387.     /** Get the constant &pi; split in two pieces.
  388.      * @return a {@link Dfp} with value &pi; split in two pieces
  389.      */
  390.     public Dfp[] getPiSplit() {
  391.         return piSplit.clone();
  392.     }

  393.     /** Get the constant e.
  394.      * @return a {@link Dfp} with value e
  395.      */
  396.     public Dfp getE() {
  397.         return e;
  398.     }

  399.     /** Get the constant e split in two pieces.
  400.      * @return a {@link Dfp} with value e split in two pieces
  401.      */
  402.     public Dfp[] getESplit() {
  403.         return eSplit.clone();
  404.     }

  405.     /** Get the constant ln(2).
  406.      * @return a {@link Dfp} with value ln(2)
  407.      */
  408.     public Dfp getLn2() {
  409.         return ln2;
  410.     }

  411.     /** Get the constant ln(2) split in two pieces.
  412.      * @return a {@link Dfp} with value ln(2) split in two pieces
  413.      */
  414.     public Dfp[] getLn2Split() {
  415.         return ln2Split.clone();
  416.     }

  417.     /** Get the constant ln(5).
  418.      * @return a {@link Dfp} with value ln(5)
  419.      */
  420.     public Dfp getLn5() {
  421.         return ln5;
  422.     }

  423.     /** Get the constant ln(5) split in two pieces.
  424.      * @return a {@link Dfp} with value ln(5) split in two pieces
  425.      */
  426.     public Dfp[] getLn5Split() {
  427.         return ln5Split.clone();
  428.     }

  429.     /** Get the constant ln(10).
  430.      * @return a {@link Dfp} with value ln(10)
  431.      */
  432.     public Dfp getLn10() {
  433.         return ln10;
  434.     }

  435.     /** Breaks a string representation up into two {@link Dfp}'s.
  436.      * The split is such that the sum of them is equivalent to the input string,
  437.      * but has higher precision than using a single Dfp.
  438.      * @param a string representation of the number to split
  439.      * @return an array of two {@link Dfp Dfp} instances which sum equals a
  440.      */
  441.     private Dfp[] split(final String a) {
  442.         Dfp[] result = new Dfp[2];
  443.         boolean leading = true;
  444.         int sp = 0;
  445.         int sig = 0;

  446.         char[] buf = new char[a.length()];

  447.         for (int i = 0; i < buf.length; i++) {
  448.             buf[i] = a.charAt(i);

  449.             if (buf[i] >= '1' && buf[i] <= '9') {
  450.                 leading = false;
  451.             }

  452.             if (buf[i] == '.') {
  453.                 sig += (400 - sig) % 4;
  454.                 leading = false;
  455.             }

  456.             if (sig == (radixDigits / 2) * 4) {
  457.                 sp = i;
  458.                 break;
  459.             }

  460.             if (buf[i] >= '0' && buf[i] <= '9' && !leading) {
  461.                 sig++;
  462.             }
  463.         }

  464.         result[0] = new Dfp(this, String.valueOf(buf, 0, sp));

  465.         for (int i = 0; i < buf.length; i++) {
  466.             buf[i] = a.charAt(i);
  467.             if (buf[i] >= '0' && buf[i] <= '9' && i < sp) {
  468.                 buf[i] = '0';
  469.             }
  470.         }

  471.         result[1] = new Dfp(this, String.valueOf(buf));

  472.         return result;
  473.     }

  474.     /** Recompute the high precision string constants.
  475.      * @param highPrecisionDecimalDigits precision at which the string constants mus be computed
  476.      */
  477.     private static void computeStringConstants(final int highPrecisionDecimalDigits) {
  478.         if (sqr2String == null || sqr2String.length() < highPrecisionDecimalDigits - 3) {

  479.             // recompute the string representation of the transcendental constants
  480.             final DfpField highPrecisionField = new DfpField(highPrecisionDecimalDigits, false);
  481.             final Dfp highPrecisionOne        = new Dfp(highPrecisionField, 1);
  482.             final Dfp highPrecisionTwo        = new Dfp(highPrecisionField, 2);
  483.             final Dfp highPrecisionThree      = new Dfp(highPrecisionField, 3);

  484.             final Dfp highPrecisionSqr2 = highPrecisionTwo.sqrt();
  485.             sqr2String           = highPrecisionSqr2.toString();
  486.             sqr2ReciprocalString = highPrecisionOne.divide(highPrecisionSqr2).toString();

  487.             final Dfp highPrecisionSqr3 = highPrecisionThree.sqrt();
  488.             sqr3String           = highPrecisionSqr3.toString();
  489.             sqr3ReciprocalString = highPrecisionOne.divide(highPrecisionSqr3).toString();

  490.             piString   = computePi(highPrecisionOne, highPrecisionTwo, highPrecisionThree).toString();
  491.             eString    = computeExp(highPrecisionOne, highPrecisionOne).toString();
  492.             ln2String  = computeLn(highPrecisionTwo, highPrecisionOne, highPrecisionTwo).toString();
  493.             ln5String  = computeLn(new Dfp(highPrecisionField, 5),  highPrecisionOne, highPrecisionTwo).toString();
  494.             ln10String = computeLn(new Dfp(highPrecisionField, 10), highPrecisionOne, highPrecisionTwo).toString();
  495.         }
  496.     }

  497.     /** Compute &pi; using Jonathan and Peter Borwein quartic formula.
  498.      * @param one constant with value 1 at desired precision
  499.      * @param two constant with value 2 at desired precision
  500.      * @param three constant with value 3 at desired precision
  501.      * @return &pi;
  502.      */
  503.     private static Dfp computePi(final Dfp one, final Dfp two, final Dfp three) {

  504.         Dfp sqrt2   = two.sqrt();
  505.         Dfp yk      = sqrt2.subtract(one);
  506.         Dfp four    = two.add(two);
  507.         Dfp two2kp3 = two;
  508.         Dfp ak      = two.multiply(three.subtract(two.multiply(sqrt2)));

  509.         // The formula converges quartically. This means the number of correct
  510.         // digits is multiplied by 4 at each iteration! Five iterations are
  511.         // sufficient for about 160 digits, eight iterations give about
  512.         // 10000 digits (this has been checked) and 20 iterations more than
  513.         // 160 billions of digits (this has NOT been checked).
  514.         // So the limit here is considered sufficient for most purposes ...
  515.         for (int i = 1; i < 20; i++) {
  516.             final Dfp ykM1 = yk;

  517.             final Dfp y2         = yk.multiply(yk);
  518.             final Dfp oneMinusY4 = one.subtract(y2.multiply(y2));
  519.             final Dfp s          = oneMinusY4.sqrt().sqrt();
  520.             yk = one.subtract(s).divide(one.add(s));

  521.             two2kp3 = two2kp3.multiply(four);

  522.             final Dfp p = one.add(yk);
  523.             final Dfp p2 = p.multiply(p);
  524.             ak = ak.multiply(p2.multiply(p2)).subtract(two2kp3.multiply(yk).multiply(one.add(yk).add(yk.multiply(yk))));

  525.             if (yk.equals(ykM1)) {
  526.                 break;
  527.             }
  528.         }

  529.         return one.divide(ak);
  530.     }

  531.     /** Compute exp(a).
  532.      * @param a number for which we want the exponential
  533.      * @param one constant with value 1 at desired precision
  534.      * @return exp(a)
  535.      */
  536.     public static Dfp computeExp(final Dfp a, final Dfp one) {

  537.         Dfp y  = new Dfp(one);
  538.         Dfp py = new Dfp(one);
  539.         Dfp f  = new Dfp(one);
  540.         Dfp fi = new Dfp(one);
  541.         Dfp x  = new Dfp(one);

  542.         for (int i = 0; i < 10000; i++) {
  543.             x = x.multiply(a);
  544.             y = y.add(x.divide(f));
  545.             fi = fi.add(one);
  546.             f = f.multiply(fi);
  547.             if (y.equals(py)) {
  548.                 break;
  549.             }
  550.             py = new Dfp(y);
  551.         }

  552.         return y;
  553.     }


  554.     /** Compute ln(a).
  555.      *
  556.      *  <pre>{@code
  557.      *  Let f(x) = ln(x),
  558.      *
  559.      *  We know that f'(x) = 1/x, thus from Taylor's theorem we have:
  560.      *
  561.      *           -----          n+1         n
  562.      *  f(x) =   \           (-1)    (x - 1)
  563.      *           /          ----------------    for 1 <= n <= infinity
  564.      *           -----             n
  565.      *
  566.      *  or
  567.      *                       2        3       4
  568.      *                   (x-1)   (x-1)    (x-1)
  569.      *  ln(x) =  (x-1) - ----- + ------ - ------ + ...
  570.      *                     2       3        4
  571.      *
  572.      *  alternatively,
  573.      *
  574.      *                  2    3   4
  575.      *                 x    x   x
  576.      *  ln(x+1) =  x - -  + - - - + ...
  577.      *                 2    3   4
  578.      *
  579.      *  This series can be used to compute ln(x), but it converges too slowly.
  580.      *
  581.      *  If we substitute -x for x above, we get
  582.      *
  583.      *                   2    3    4
  584.      *                  x    x    x
  585.      *  ln(1-x) =  -x - -  - -  - - + ...
  586.      *                  2    3    4
  587.      *
  588.      *  Note that all terms are now negative.  Because the even powered ones
  589.      *  absorbed the sign.  Now, subtract the series above from the previous
  590.      *  one to get ln(x+1) - ln(1-x).  Note the even terms cancel out leaving
  591.      *  only the odd ones
  592.      *
  593.      *                             3     5      7
  594.      *                           2x    2x     2x
  595.      *  ln(x+1) - ln(x-1) = 2x + --- + --- + ---- + ...
  596.      *                            3     5      7
  597.      *
  598.      *  By the property of logarithms that ln(a) - ln(b) = ln (a/b) we have:
  599.      *
  600.      *                                3        5        7
  601.      *      x+1           /          x        x        x          \
  602.      *  ln ----- =   2 *  |  x  +   ----  +  ----  +  ---- + ...  |
  603.      *      x-1           \          3        5        7          /
  604.      *
  605.      *  But now we want to find ln(a), so we need to find the value of x
  606.      *  such that a = (x+1)/(x-1).   This is easily solved to find that
  607.      *  x = (a-1)/(a+1).
  608.      * }</pre>
  609.      * @param a number for which we want the exponential
  610.      * @param one constant with value 1 at desired precision
  611.      * @param two constant with value 2 at desired precision
  612.      * @return ln(a)
  613.      */

  614.     public static Dfp computeLn(final Dfp a, final Dfp one, final Dfp two) {

  615.         int den = 1;
  616.         Dfp x = a.add(new Dfp(a.getField(), -1)).divide(a.add(one));

  617.         Dfp y = new Dfp(x);
  618.         Dfp num = new Dfp(x);
  619.         Dfp py = new Dfp(y);
  620.         for (int i = 0; i < 10000; i++) {
  621.             num = num.multiply(x);
  622.             num = num.multiply(x);
  623.             den += 2;
  624.             Dfp t = num.divide(den);
  625.             y = y.add(t);
  626.             if (y.equals(py)) {
  627.                 break;
  628.             }
  629.             py = new Dfp(y);
  630.         }

  631.         return y.multiply(two);
  632.     }
  633. }