Java中BigDecimal的平方根

66

我们能否在Java中仅使用Java API而不是自定义的100行算法来计算一个BigDecimal的平方根?


1
不用编写自己的算法?达到所需的精度?不可能。 - Louis Wasserman
6
要不要考虑定制一个50行的算法,包括注释?牛顿迭代法并不是很复杂。 - Patricia Shanahan
1
从Java 9开始,您可以使用BigDecimal.sqrt()方法实现!@dimo414对这个问题给出了正确的答案。 - Tim
12个回答

0
public static BigDecimal sqrt( final BigDecimal value )
{
    BigDecimal guess = value.multiply( DECIMAL_HALF ); 
    BigDecimal previousGuess;

    do
    {
        previousGuess = guess;
        guess = sqrtGuess( guess, value );
   } while ( guess.subtract( previousGuess ).abs().compareTo( EPSILON ) == 1 );

    return guess;
}

private static BigDecimal sqrtGuess( final BigDecimal guess,
                                     final BigDecimal value )
{
    return guess.subtract( guess.multiply( guess ).subtract( value ).divide( DECIMAL_TWO.multiply( guess ), SCALE, RoundingMode.HALF_UP ) );
}

private static BigDecimal epsilon()
{
    final StringBuilder builder = new StringBuilder( "0." );

    for ( int i = 0; i < SCALE - 1; ++i )
    {
        builder.append( "0" );
    }

    builder.append( "1" );

    return new BigDecimal( builder.toString() );
}

private static final int SCALE = 1024;
private static final BigDecimal EPSILON = epsilon();
public static final BigDecimal DECIMAL_HALF = new BigDecimal( "0.5" );
public static final BigDecimal DECIMAL_TWO = new BigDecimal( "2" );

-2
BigDecimal.valueOf(Math.sqrt(myBigDecimal.doubleValue()));

10
我认为你需要明确指出,这只有在接受double精度答案的情况下才足够,而且前提是原始的BigDecimal在double允许的范围内。通常使用BigDecimal的全部理由就是其中一个或两个条件不成立。 - Neil Coffey
2
好的,这里使用了 doubleValue() 方法,这意味着我可能会失去很多精度,但另一方面我的问题是“如何仅使用JAVA API”,所以非常感谢您提供的帮助。我将使用它,无论发生什么事情,都会接受。 - user1853200
15
这样做违背了 BigDecimal 的目的。 - uthomas
1
使用BigDecimal的整个目的是为了实现高精度。 - user1613360
@uthomas 不一定,如果你很幸运地遇到只需要精确计算其他与平方根有关的计算,那么你可以使用BigDecimal。 - Kröw
当执行 myBigDecimal.doubleValue() 时,我们会失去精度,然后我们对一个不太精确的值进行计算,最后再将其转换回 Bigdecimal - uthomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接