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