public static BigDecimal intRoot ( @ Nonnull final BigDecimal px , final long index , final int scale ) { BigDecimal x = px ; // Check that x >= 0. if ( x . signum ( ) < 0 ) { throw new IllegalArgumentException ( "x < 0: " + x ) ; } final int sp1 = scale + 1 ; final BigDecimal n = x ; final BigDecimal i = BigDecimal . valueOf ( index ) ; final BigDecimal im1 = BigDecimal . valueOf ( index - 1 ) ; final BigDecimal tolerance = BigDecimal . valueOf ( 5 ) . movePointLeft ( sp1 ) ; BigDecimal xPrev ; // The initial approximation is x/index. x = x . divide ( i , scale , RoundingMode . HALF_EVEN ) ; // Loop until the approximations converge // (two successive approximations are equal after rounding). do { // x^(index-1) final BigDecimal xToIm1 = intPower ( x , index - 1 , sp1 ) ; // x^index final BigDecimal xToI = x . multiply ( xToIm1 ) . setScale ( sp1 , RoundingMode . HALF_EVEN ) ; // n + (index-1)*(x^index) final BigDecimal numerator = n . add ( im1 . multiply ( xToI ) ) . setScale ( sp1 , RoundingMode . HALF_EVEN ) ; // (index*(x^(index-1)) final BigDecimal denominator = i . multiply ( xToIm1 ) . setScale ( sp1 , RoundingMode . HALF_EVEN ) ; // x = (n + (index-1)*(x^index)) / (index*(x^(index-1))) xPrev = x ; x = numerator . divide ( denominator , sp1 , RoundingMode . DOWN ) ; Thread . yield ( ) ; } while ( x . subtract ( xPrev ) . abs ( ) . compareTo ( tolerance ) > 0 ) ; return x ; }
Compute the integral root of x to a given scale x &ge ; 0 . Use Newton s algorithm .