private static BigDecimal _lnNewton ( @ Nonnull final BigDecimal px , final int scale ) { BigDecimal x = px ; final int sp1 = scale + 1 ; final BigDecimal n = x ; BigDecimal term ; // Convergence tolerance = 5*(10^-(scale+1)) final BigDecimal tolerance = BigDecimal . valueOf ( 5 ) . movePointLeft ( sp1 ) ; // Loop until the approximations converge // (two successive approximations are within the tolerance). do { // e^x final BigDecimal eToX = exp ( x , sp1 ) ; // (e^x - n)/e^x term = eToX . subtract ( n ) . divide ( eToX , sp1 , RoundingMode . DOWN ) ; // x - (e^x - n)/e^x x = x . subtract ( term ) ; Thread . yield ( ) ; } while ( term . compareTo ( tolerance ) > 0 ) ; return x . setScale ( scale , RoundingMode . HALF_EVEN ) ; }
Compute the natural logarithm of x to a given scale x > 0 . Use Newton s algorithm .