Anyone know how I can take the square root of a bigDecimal with keeping the precision. I found the BigDecimal method pow(), so I could take the power to the .5. But this method only accepts ints.

Printable View

- 05-20-2011, 07:27 PMryanmk54square rooting a BigDecimal
Anyone know how I can take the square root of a bigDecimal with keeping the precision. I found the BigDecimal method pow(), so I could take the power to the .5. But this method only accepts ints.

- 05-20-2011, 08:58 PMJodokusCode:
`package bigroot;`

import java.math.BigDecimal;

import java.math.BigInteger;

//sqrt-function copied of BigFunctionsClass

//From The Java Programmers Guide To numerical Computing (Ronald Mak, 2003)

public class BigRoot {

/**

* Compute the square root of x to a given scale, x >= 0.

* Use Newton's algorithm.

* @param x the value of x

* @param scale the desired scale of the result

* @return the result value

*/

public static BigDecimal sqrt(BigDecimal x, int scale)

{

// Check that x >= 0.

if (x.signum() < 0) {

throw new IllegalArgumentException("x < 0");

}

// n = x*(10^(2*scale))

BigInteger n = x.movePointRight(scale << 1).toBigInteger();

// The first approximation is the upper half of n.

int bits = (n.bitLength() + 1) >> 1;

BigInteger ix = n.shiftRight(bits);

BigInteger ixPrev;

// Loop until the approximations converge

// (two successive approximations are equal after rounding).

do {

ixPrev = ix;

// x = (x + n/x)/2

ix = ix.add(n.divide(ix)).shiftRight(1);

Thread.yield();

} while (ix.compareTo(ixPrev) != 0);

return new BigDecimal(ix, scale);

}

}

Code:`package bigroot;`

import java.math.BigDecimal;

/**

* Test the BigFunctions by comparing results with class java.lang.Math.

*/

public class TestBigRoot

{

private static final int SCALE = 40;

private void run()

{

System.out.println("sqrt 2 = " + Math.sqrt(2));

System.out.println(" = " + BigRoot.sqrt(BigDecimal.valueOf(2), SCALE));

System.out.println("sqrt 26 = " + Math.sqrt(26));

System.out.println(" = " + BigRoot.sqrt(BigDecimal.valueOf(26), SCALE));

}

public static void main(String args[])

{

TestBigRoot test = new TestBigRoot();

try {

test.run();

}

catch(Exception ex) {

System.out.println("ERROR: " + ex.getMessage());

}

}

}

- 05-20-2011, 09:05 PMJosAH
- 05-20-2011, 10:28 PMryanmk54
Thanks. I am not going to try to understand it now, but it does a great job of what I want it to.

- 05-21-2011, 04:28 PMJosAH
- 05-21-2011, 04:34 PMFubarable
- 05-21-2011, 04:42 PMJosAH
- 05-21-2011, 05:32 PMJodokusQuote:

My reply #3 (accidentally) described how the method in reply #2 works.

- 05-21-2011, 05:42 PMJosAH
- 05-21-2011, 10:57 PMryanmk54
I am just making a basic calculator. I read a forum post a while back that said if you are adding money or anything like that you should never use double. You should use BigDecimal.

Were you suggesting I convert the BigDecimal to an int or just use double? I haven't made very much java yet. I just do it in my spare time. - 05-21-2011, 11:16 PMJosAH
Are you making a general purpose (basic) calculator, or are you building a financial calculator? If it's the former, ordinary doubles would do fine (unless you want unlimited precision). If it is a financial calculator it depends on the type of calculations you want to perform. So, it's your turn to elaborate on this ;-)

kind regards,

Jos - 05-21-2011, 11:36 PMryanmk54
- 05-21-2011, 11:56 PMJodokus
Just a warning: you'll need a book then like mentioned in the listing, and Jos/Fubarable are right, working with doubles is almost allways more then needed (and a good, (not-Polish-notation-) calculator is difficult enough). But it would be a challenge. Tell here when you're done!

- 05-22-2011, 03:33 AMryanmk54
Is polish notation where you can enter like five operations at once (5+6*5-9+1). My calculator is extremely basic. Two numbers an operator and answer. It works right now but I'm still planning on adding some features(menu bar , log window, .

rounding preferences, etc) - 05-22-2011, 03:53 AMpbrockway2
No in polish notation your example would be entered as 5,6,5,*,+,9,1,+,- (I think!)

The nice thing is that the order of operations is unambiguously specified without parentheses. The downside is that only Poles can understand it.

The notation is described at Polish notation - Wikipedia, the free encyclopedia - the example I gave seems to be Reverse Polish notation - Wikipedia, the free encyclopedia. - 05-22-2011, 11:03 AMJosAH
Yep, also, if the arity of the operators/functions is known and fixed you don't need those irritating parentheses in Polish notation either, e.g. 3*(4+5) is * 3 + 4 5 in Polish notation and is unambiguous, as is the reverse Polish notation 3 4 5 + * It's the variadic functions/operators that mess things up, e.g. (+ 1 2 3) where the + operator takes three arguments. There also is the functional notation (sometimes called 'outer Lisp') where the operators are used as functions, so 3*(4+5) is written as *(3, +(4, 5)). If the comma isn't a function/operator itself it can be left out.

kind regards,

Jos - 05-22-2011, 01:13 PMJodokus
I just can't leave for a moment! The explanations of Jos and PBrockway are perfect, and google also knows something about it. I just mentioned it because it is supposedly easier to program: you don't need the parsing. But indeed, only Polish people seem to understand or like it.

(In effect what you do on a small calculator with just an in-between result showing is a bit like reverse Polish notation (but cheating by using a memory): just enter arguments followed by an operator all the time.) - 05-22-2011, 01:59 PMJosAH
That's not entirely true, all three forms need a bit of parsing, e.g. + * - doesn't make sense for a postfix expression (reverse Polish) if there are no operands available on the data stack; equivalently * 3 - doesn't make sense as an infix expression, nor does it as a prefix expression (Polish notation). On the other hand those parsers are minimal compared to the lexical analyzers needed in all three of the expression forms.

kind regards,

Jos