public static double log1p(final double value){
  if (USE_JDK_MATH) {
    return Math.log1p(value);
  }
  if (value > -1.0) {
    if (value == Double.POSITIVE_INFINITY) {
      return Double.POSITIVE_INFINITY;
    }
    final double valuePlusOne=1.0 + value;
    if (valuePlusOne == 1.0) {
      return value;
    }
 else     if (Math.abs(value) < 0.15) {
      final double z=value / (value + 2.0);
      final 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))))));
    }
    final int valuePlusOneBitsHi=(int)(Double.doubleToRawLongBits(valuePlusOne) >> 32) & 0x7FFFFFFF;
    final int valuePlusOneExp=(valuePlusOneBitsHi >> 20) - MAX_DOUBLE_EXPONENT;
    final int xIndex=valuePlusOneBitsHi << 12 >>> 32 - LOG_BITS;
    double z=valuePlusOne * twoPowNormalOrSubnormal(-valuePlusOneExp) * MyTLog.logXInvTab[xIndex] - 1;
    z*=1 - z * (1.0 / 2 - z * (1.0 / 3));
    return valuePlusOneExp * LOG_2 + MyTLog.logXLogTab[xIndex] + (z + (value - (valuePlusOne - 1)) / valuePlusOne);
  }
 else   if (value == -1.0) {
    return Double.NEGATIVE_INFINITY;
  }
 else {
    return Double.NaN;
  }
}

public static double log1p ( final double value ) { if ( USE_JDK_MATH ) { return Math . log1p ( value ) ; } if ( value > - 1.0 ) { if ( value == Double . POSITIVE_INFINITY ) { return Double . POSITIVE_INFINITY ; } final double valuePlusOne = 1.0 + value ; if ( valuePlusOne == 1.0 ) { return value ; } else if ( Math . abs ( value ) < 0.15 ) { final double z = value / ( value + 2.0 ) ; final 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 ) ) ) ) ) ) ; } final int valuePlusOneBitsHi = ( int ) ( Double . doubleToRawLongBits ( valuePlusOne ) > > 32 ) & 0x7FFFFFFF ; final int valuePlusOneExp = ( valuePlusOneBitsHi > > 20 ) - MAX_DOUBLE_EXPONENT ; final int xIndex = valuePlusOneBitsHi << 12 > > > 32 - LOG_BITS ; double z = valuePlusOne * twoPowNormalOrSubnormal ( - valuePlusOneExp ) * MyTLog . logXInvTab [ xIndex ] - 1 ; z *= 1 - z * ( 1.0 / 2 - z * ( 1.0 / 3 ) ) ; return valuePlusOneExp * LOG_2 + MyTLog . 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 arguments ( and results ) close to zero .
