public static double log1p(double value){
  if (USE_JDK_MATH) {
    return STRICT_MATH ? StrictMath.log1p(value) : Math.log1p(value);
  }
  if (false) {
    if (value == Double.POSITIVE_INFINITY) {
      return Double.POSITIVE_INFINITY;
    }
    double valuePlusOne=1 + value;
    if (valuePlusOne == 1.0) {
      return value;
    }
 else {
      return FastMath.log(valuePlusOne) * (value / (valuePlusOne - 1.0));
    }
  }
  if (value > -1.0) {
    if (value == Double.POSITIVE_INFINITY) {
      return Double.POSITIVE_INFINITY;
    }
    double valuePlusOne=1.0 + value;
    if (valuePlusOne == 1.0) {
      return value;
    }
 else     if (Math.abs(value) < 0.15) {
      double z=value / (value + 2.0);
      double z2=z * z;
      return z * (2 + z2 * ((2.0 / 3) + z2 * ((2.0 / 5) + z2 * ((2.0 / 7) + z2 * ((2.0 / 9) + z2 * ((2.0 / 11)))))));
    }
    int valuePlusOneBitsHi=(int)(Double.doubleToRawLongBits(valuePlusOne) >> 32) & 0x7FFFFFFF;
    int valuePlusOneExp=(valuePlusOneBitsHi >> 20) - MAX_DOUBLE_EXPONENT;
    int xIndex=((valuePlusOneBitsHi << 12) >>> (32 - LOG_BITS));
    double z=(valuePlusOne * twoPowTab[-valuePlusOneExp - MIN_DOUBLE_EXPONENT]) * logXInvTab[xIndex] - 1;
    z*=(1 - z * ((1.0 / 2) - z * (1.0 / 3)));
    return valuePlusOneExp * LOG_2 + logXLogTab[xIndex] + (z + (value - (valuePlusOne - 1)) / valuePlusOne);
  }
 else   if (value == -1.0) {
    return Double.NEGATIVE_INFINITY;
  }
 else {
    return Double.NaN;
  }
}

public static double log1p ( double value ) { if ( USE_JDK_MATH ) { return STRICT_MATH ? StrictMath . log1p ( value ) : Math . log1p ( value ) ; } if ( false ) { if ( value == Double . POSITIVE_INFINITY ) { return Double . POSITIVE_INFINITY ; } double valuePlusOne = 1 + value ; if ( valuePlusOne == 1.0 ) { return value ; } else { return FastMath . log ( valuePlusOne ) * ( value / ( valuePlusOne - 1.0 ) ) ; } } if ( value > - 1.0 ) { if ( value == Double . POSITIVE_INFINITY ) { return Double . POSITIVE_INFINITY ; } double valuePlusOne = 1.0 + value ; if ( valuePlusOne == 1.0 ) { return value ; } else if ( Math . abs ( value ) < 0.15 ) { double z = value / ( value + 2.0 ) ; double z2 = z * z ; return z * ( 2 + z2 * ( ( 2.0 / 3 ) + z2 * ( ( 2.0 / 5 ) + z2 * ( ( 2.0 / 7 ) + z2 * ( ( 2.0 / 9 ) + z2 * ( ( 2.0 / 11 ) ) ) ) ) ) ) ; } int valuePlusOneBitsHi = ( int ) ( Double . doubleToRawLongBits ( valuePlusOne ) > > 32 ) & 0x7FFFFFFF ; int valuePlusOneExp = ( valuePlusOneBitsHi > > 20 ) - MAX_DOUBLE_EXPONENT ; int xIndex = ( ( valuePlusOneBitsHi << 12 ) > > > ( 32 - LOG_BITS ) ) ; double z = ( valuePlusOne * twoPowTab [ - valuePlusOneExp - MIN_DOUBLE_EXPONENT ] ) * logXInvTab [ xIndex ] - 1 ; z *= ( 1 - z * ( ( 1.0 / 2 ) - z * ( 1.0 / 3 ) ) ) ; return valuePlusOneExp * LOG_2 + logXLogTab [ xIndex ] + ( z + ( value - ( valuePlusOne - 1 ) ) / valuePlusOne ) ; } else if ( value == - 1.0 ) { return Double . NEGATIVE_INFINITY ; } else { return Double . NaN ; } }
much more accurate than log ( 1 + value ) , for values close to zero .
