30

Are there any libraries for Square Root over BigDecimal in Java?

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • I wonder, why do you need to compute square roots of a BigDecimal? Double has too small range? – quant_dev Sep 06 '09 at 18:44
  • 13
    For the same reason anyone uses BigDecimal: double lacks precision. – Daniel C. Sobral Sep 07 '09 at 01:09
  • Daniel, but so does the computation of square root. You cannot compute sqrt(2) with infinite precision. Using Newton method to calculate the square root introduces an error of its own, inherent in the algorithm. – quant_dev Sep 07 '09 at 20:02
  • 7
    Err, no. Double an BigDecimal are inherently different. Double "precision" depends on the number you are representing. Some are just impossible to represent within any precision. With BigDecimal the precision can be arbitrarily set, and, within that precision, you can represent any fractional number. – Daniel C. Sobral Sep 08 '09 at 01:54
  • 1
    Numbers like 1/3 cannot be represented 100% precisely in a decimal base without using an infinite number of digit. What is more, numbers like sqrt(2) cannot be represented in *any* base without using an infinite number of digits. This is a mathematical fact. As for the *computation* of square roots, using Newton's method gives you another source of inaccuracy. How do you know, using Newton's method, that the first N digits of your computed square root are correct? There methods for that, but Newton's method is not one of them: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots – quant_dev Sep 08 '09 at 06:12
  • "A little learning is a dangerous thing; drink deep, or taste not the Pierian spring: there shallow draughts intoxicate the brain, and drinking largely sobers us again." – quant_dev Sep 08 '09 at 06:41
  • @quant_dev: are you misreading on purpose? With BigDecimal I can control the precision, with a floating point number I can't. With BigDecimal I can emphatically say that my precision is, for instance, 1 point decimal. So, try this, for instance: 10000000000000000D + 0.1D == 1E16 and tell me the result. – Daniel C. Sobral Sep 08 '09 at 18:19
  • Daniel, you are ignoring the context of the question: computation of the square root. Think about Newton's method computes the square root, and whether having arbitrary precision can help you find the result with arbitrary accuracy. – quant_dev Sep 08 '09 at 20:01
  • Well, if you want to criticise the answer, do so, *below the answer*. Below the question I'm only discussing *the question*. – Daniel C. Sobral Sep 08 '09 at 22:07
  • Well, dude, I commented the question in my first comment, and then you came over and hijacked the topic. – quant_dev Sep 08 '09 at 23:40
  • 5
    No hi-jacking. I need it for the same reason anyone uses BigDecimal: Double lacks precision. BigDecimal gives me the precision I ask it for, Double doesn't. You then introduced a criticism to Newton's method, which is irrelevant to the question. I rebutted the remaining statements, and you brought Newton's method again. Well, do criticise it below the answer that refers to Newton's method, and leave the question well alone -- or bring something new and relevant to it. – Daniel C. Sobral Sep 09 '09 at 00:00
  • OK, so using BigDecimal you can have more digits in your final result (the square root). Did you verify that these digits make any sense? – quant_dev Sep 09 '09 at 18:05

3 Answers3

14

JScience v4.3.1 has a Real class which seems to be the equivalent of BigDecimal and that might help you. An example of usage:

// The Square Root of Two, to 30 digits
// According to "The Square Root of Two, to 5 million digits."
// Source: http://www.gutenberg.org/files/129/129.txt
System.out.println("1.41421356237309504880168872420");

// Using JScience with 50 digits precision
Real.setExactPrecision(50);
System.out.println(Real.valueOf(2).sqrt());

// Using default java implementation
System.out.println(Math.sqrt(2));

> 1.41421356237309504880168872420
> 1.414213562373095048801689
> 1.4142135623730951

Edit: Updated the code and the links to reflect the current version at the time (v4.3.1). Based on @ile an @Tomasz comments, thanks.

Redder
  • 1,398
  • 1
  • 11
  • 16
  • I downloaded the JScience package and it seems there is no Decimal anymore . The link above is broken. – ılǝ Mar 01 '13 at 17:31
  • It has a LargeInteger class which seems equivalent http://jscience.org/api/org/jscience/mathematics/number/LargeInteger.html – Master_ex Mar 12 '13 at 19:09
  • Decimal has bee replaced by Real http://jscience.org/api/org/jscience/mathematics/number/Real.html – Tomasz Apr 27 '13 at 03:37
  • And what can We do if that numbers are not int or double but BigDecimal? – codebusta Jun 24 '14 at 13:24
12

Try Big Square Roots. It uses the Newton's method for approximating solutions such as square roots.

greybeard
  • 2,249
  • 8
  • 30
  • 66
cletus
  • 616,129
  • 168
  • 910
  • 942
1

(This is may not be a solution for you)

As long as your BigDecimal is in the range of double, you can convert the BigDecimal to double, use Math.sqrt() and promote the double back to BigDecimal. It will probably be faster than carrying out the calculation on BigDecimals. In many cases the loss of precision due to conversion between types will be negligible compared to the inevitable error in computing the square root.

quant_dev
  • 6,181
  • 1
  • 34
  • 57