Program: 57079
Project: 57079
Buggy source:
/** 
 * Compute ln(a). Let f(x) = ln(x), We know that f'(x) = 1/x, thus from Taylor's theorem we have: -----          n+1         n f(x) =   \           (-1)    (x - 1) /          ----------------    for 1 <= n <= infinity -----             n or 2        3       4 (x-1)   (x-1)    (x-1) ln(x) =  (x-1) - ----- + ------ - ------ + ... 2       3        4 alternatively, 2    3   4 x    x   x ln(x+1) =  x - -  + - - - + ... 2    3   4 This series can be used to compute ln(x), but it converges too slowly. If we substitute -x for x above, we get 2    3    4 x    x    x ln(1-x) =  -x - -  - -  - - + ... 2    3    4 Note that all terms are now negative.  Because the even powered ones absorbed the sign.  Now, subtract the series above from the previous one to get ln(x+1) - ln(1-x).  Note the even terms cancel out leaving only the odd ones 3     5      7 2x    2x     2x ln(x+1) - ln(x-1) = 2x + --- + --- + ---- + ... 3     5      7 By the property of logarithms that ln(a) - ln(b) = ln (a/b) we have: 3        5        7 x+1           /          x        x        x          \ ln ----- =   2 *  |  x  +   ----  +  ----  +  ---- + ...  | x-1           \          3        5        7          / But now we want to find ln(a), so we need to find the value of x such that a = (x+1)/(x-1).   This is easily solved to find that x = (a-1)/(a+1).
 * @param a number for which we want the exponential
 * @param one constant with value 1 at desired precision
 * @param two constant with value 2 at desired precision
 * @return ln(a)
 */
public static Dfp computeLn(final Dfp a,final Dfp one,final Dfp two){
  int den=1;
  Dfp x=a.add(new Dfp(a.getField(),-1)).divide(a.add(one));
  Dfp y=new Dfp(x);
  Dfp num=new Dfp(x);
  Dfp py=new Dfp(y);
  for (int i=0; i < 10000; i++) {
    num=num.multiply(x);
    num=num.multiply(x);
    den+=2;
    Dfp t=num.divide(den);
    y=y.add(t);
    if (y.equals(py)) {
      break;
    }
    py=new Dfp(y);
  }
  return y.multiply(two);
}

Fixed version (ground truth):
/** 
 * Compute ln(a). <pre>  {@code Let f(x) = ln(x), We know that f'(x) = 1/x, thus from Taylor's theorem we have: -----          n+1         n f(x) =   \           (-1)    (x - 1) /          ----------------    for 1 <= n <= infinity -----             n or 2        3       4 (x-1)   (x-1)    (x-1) ln(x) =  (x-1) - ----- + ------ - ------ + ... 2       3        4 alternatively, 2    3   4 x    x   x ln(x+1) =  x - -  + - - - + ... 2    3   4 This series can be used to compute ln(x), but it converges too slowly. If we substitute -x for x above, we get 2    3    4 x    x    x ln(1-x) =  -x - -  - -  - - + ... 2    3    4 Note that all terms are now negative.  Because the even powered ones absorbed the sign.  Now, subtract the series above from the previous one to get ln(x+1) - ln(1-x).  Note the even terms cancel out leaving only the odd ones 3     5      7 2x    2x     2x ln(x+1) - ln(x-1) = 2x + --- + --- + ---- + ... 3     5      7 By the property of logarithms that ln(a) - ln(b) = ln (a/b) we have: 3        5        7 x+1           /          x        x        x          \ ln ----- =   2 *  |  x  +   ----  +  ----  +  ---- + ...  | x-1           \          3        5        7          / But now we want to find ln(a), so we need to find the value of x such that a = (x+1)/(x-1).   This is easily solved to find that x = (a-1)/(a+1).}</pre>
 * @param a number for which we want the exponential
 * @param one constant with value 1 at desired precision
 * @param two constant with value 2 at desired precision
 * @return ln(a)
 */
public static Dfp computeLn(final Dfp a,final Dfp one,final Dfp two){
  int den=1;
  Dfp x=a.add(new Dfp(a.getField(),-1)).divide(a.add(one));
  Dfp y=new Dfp(x);
  Dfp num=new Dfp(x);
  Dfp py=new Dfp(y);
  for (int i=0; i < 10000; i++) {
    num=num.multiply(x);
    num=num.multiply(x);
    den+=2;
    Dfp t=num.divide(den);
    y=y.add(t);
    if (y.equals(py)) {
      break;
    }
    py=new Dfp(y);
  }
  return y.multiply(two);
}