65.9K
CodeProject is changing. Read more.
Home

Implementing SqrtRoot in BigDecimal

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (2 votes)

Sep 20, 2011

CPOL

1 min read

viewsIcon

20752

Implementing SqrtRoot in BigDecimal

Introduction

Recently, I encountered a lack of precision in a math problem. Most of the people don't know that using float or double is not as good as we think that it is. So after Googling my problem, I found that I could use BigDecimal class to solve the problem. BigDecimal is used in programs that deal with currency problems. So add and subtraction are very well implemented.

So I decided to use BigDecimal and even though it's kind of annoying to replace the classic operands with "add." , "subtraction", etc. everything was doing OK. Until I need to replace the Square Root! Where is the Square Root? Well, BigDecimal doesn't implement Square Root so I decided to implement my own method. I remember back in college that we used to calculate squareRoot using "Newton Raphson Method". This method uses a Mathematics Sequence to find out the square root.

Using the Code

I will only code a static method that could be used to create a new Class to replace BigDecimal.

It may surprise you that a simple division like "1/3" will throw an exception. BigDecimal likes to be precised and "0.3333...." is not! So you will have to define the precision in any division. I will use two constans "SQRT_DIG" & "SQRT_PRE" to define how many digits I want.

private static final BigDecimal SQRT_DIG = new BigDecimal(150);
private static final BigDecimal SQRT_PRE = new BigDecimal(10).pow(SQRT_DIG.intValue());

private static BigDecimal sqrtNewtonRaphson  (BigDecimal c, BigDecimal xn, BigDecimal precision)
	{
		BigDecimal fx = xn.pow(2).add(c.negate());
		BigDecimal fpx = xn.multiply(new BigDecimal(2));
		BigDecimal xn1 = fx.divide(fpx,2*SQRT_DIG.intValue(),RoundingMode.HALF_DOWN);
		xn1 = xn.add(xn1.negate());
		//----
		BigDecimal currentSquare = xn1.pow(2);
		BigDecimal currentPrecision = currentSquare.subtract(c);
		currentPrecision = currentPrecision.abs();
		if ( currentPrecision.compareTo(precision) <= -1 )
		{
			return xn1;
		}
		return sqrtNewtonRaphson(c, xn1,precision);
	}
	
	public static BigDecimal bigSqrt(BigDecimal c)
	{
		return sqrtNewtonRaphson(c,new BigDecimal(1),new BigDecimal(1).divide(SQRT_PRE));
	}
The method to get any Square Root is bigSqrt. As you can see, sqrtNewtonRaphson will call itself until it gets the precision that you want.