# square rooting a BigDecimal

• 05-20-2011, 06:27 PM
ryanmk54
square 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, 07:58 PM
Jodokus
Code:

```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());                 }             }         }```
Don't ask me to explain the code, I just copied it and hope not to get sued. Also in the 26-test there seems to be a rounding error, but I don't know if Math or this algorithm is to blame.
• 05-20-2011, 08:05 PM
JosAH
Quote:

Originally Posted by ryanmk54
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.

A fast iteration method is: sq(n) = (n/sq(n-1)+sq(n-1))/2 and a reasonable estimation for sq(0) = n/2.

kind regards,

Jos
• 05-20-2011, 09:28 PM
ryanmk54
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, 03:28 PM
JosAH
Quote:

Originally Posted by ryanmk54
Thanks. I am not going to try to understand it now, but it does a great job of what I want it to.

My reply #3 (accidentally) described how the method in reply #2 works: take the average of the current estimation and the result of the estimation. The fixed point of the recurrence relation has to be sqrt(n). It converges quadratically.

kind regards,

Jos
• 05-21-2011, 03:34 PM
Fubarable
Quote:

Originally Posted by ryanmk54
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.

I'm curious what application requires this degree of precision for what is essentially a floating point operation.
• 05-21-2011, 03:42 PM
JosAH
Quote:

Originally Posted by Fubarable
I'm curious what application requires this degree of precision for what is essentially a floating point operation.

Me too; a bit of algebra normally cancels out those square roots ...

kind regards,

Jos
• 05-21-2011, 04:32 PM
Jodokus
Quote:

My reply #3 (accidentally) described how the method in reply #2 works.
Thanks. I admit I didn't notice it.
• 05-21-2011, 04:42 PM
JosAH
Quote:

Originally Posted by Jodokus
Thanks. I admit I didn't notice it.

Nevermind; almost nobody does ;-) my replies are too small or too technical or not enough spoonfeeding; they seem mostly invisible ;-)

kind regards,

Jos (who?)
• 05-21-2011, 09:57 PM
ryanmk54
Quote:

Originally Posted by Fubarable
I'm curious what application requires this degree of precision for what is essentially a floating point operation.

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, 10:16 PM
JosAH
Quote:

Originally Posted by ryanmk54
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.

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, 10:36 PM
ryanmk54
Quote:

Originally Posted by JosAH
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

Its just a general purpose calculator. I think I'll stick with BigDecimal because I like the automatic scaling ability
• 05-21-2011, 10:56 PM
Jodokus
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, 02:33 AM
ryanmk54
Quote:

Originally Posted by Jodokus
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!

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, 02:53 AM
pbrockway2
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, 10:03 AM
JosAH
Quote:

Originally Posted by pbrockway2
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.

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, 12:13 PM
Jodokus
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, 12:59 PM
JosAH
Quote:

Originally Posted by Jodokus
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 Polish notation (but cheating by using a memory): just enter arguments followed by an operator all the time.)

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