# Android Questionhow do i sqrt accurately?

#### ramin83karimi

##### Member
hi
i have written the following piece of code:
B4X:
``````Dim pi As BigDecimal
pi.Initialize(0)
Dim b As BigDecimal
Dim c As BigDecimal
c.Initialize(0)
b.Initialize(0)
Dim t As Long
t=DateTime.Now
For i=1 To 1000000
c.Initialize(i)
c.Multiply(c)
b.Initialize(1)
b.Divide2(c,100,0)
Next
c.Initialize(6)
pi.Multiply(c)
Log(pi)
Log(DateTime.Now-t)``````
i used the "big numbers" library to get some accurate results
at the end the program logs pi squared, and i need to square-root it accurately, but with the core options in b4x i don't think that's possible.
i tried using the same "big numbers" library to do that but it seems that it doesn't have a sqrt function
i even tried using "pow" in that library which is the equivalent of power in core, i thought i could take it to the power of 0.5 which should be the equivalent of sqrt, but "pow" only accepts integers as an input and 0.5 is floating
.
any ideas what i should do?

#### Brian Dean

##### Well-Known Member
Longtime User
any ideas what i should do?

If nobody else has a better idea, how about calculating the square root yourself? The algorithm is not very complicated - you start with a guess, divide your number by that guess, and the average of the result and the guess is a better approximation to the square root. Continue until you reach the required accuracy ...
B4X:
``````Sub squareRoot(number As Double) As Double
Dim guess As Double = number / 2    ' Start with a wild guess
Dim result As Double
Dim error As Double = 1.0
Do While (error > 0.000000001)        ' Set error at any preferred value
result = number / guess
error = Abs(guess - result)            ' How close have we got?
guess = (guess + result) / 2    ' Use average of this guess and result
Loop
Return guess
End Sub``````
Given the value PI this algoritm returns ...
1.5707963267948966
1.7853981633974483
1.7725007746756094
1.772453851526627
1.7724538509055159
1.772453850905516

Last edited:

#### drgottjr

##### Expert
Longtime User
not sure what the issue is with b4a's sqrt method, but it you want java's sqrt() from java.lang.Math, you can do what's in the attached. i did it with b4j and the bigdecimal library because it's easier to throw together. should build easily enough with b4a

i don't know what a bigdecimal is, but it wasn't too difficult to use the library in conjunction with java's sqrt() method, as if it were included in the library (which is, judging by looking at the code, based on various facets of the java.lang.Match class. you can pass a normaldecimal to the call or - as i did - pass a bigdecimal's value (a bigdecimal is an object).

b4j happens to have a PI constant, so i used it for testing. the sqrt returned was 1.7724538509055159 (which looks like something shown in a previous answer).

#### Attachments

• capture.png
8.5 KB · Views: 242

#### Mahares

##### Expert
Longtime User
not sure what the issue is with b4a's sqrt method
I am like you. I am not sure what the issue is either, but I used your javaobject method and the normal B4A sqrt function. Both yield the same result.
B4X:
``````Dim jo As JavaObject
jo.InitializeStatic("java.lang.Math")
Log(jo.RunMethod("sqrt",Array(cPI))) '1.7724538509055159
Log(Sqrt(cPI)) '1.7724538509055159``````

#### emexes

##### Expert
Both yield the same result
being the square root of pi to 53 bits ie IEEE 754 double precision

Last edited:

#### OliverA

##### Expert
Longtime User
but with the core options in b4x
Technically nothing to do with B4X (B4A in this case) since square root method for BigDecimal was not added until Java 9 (https://www.geeksforgeeks.org/bigdecimal-sqrt-method-in-java-with-examples/). Adapting @Brian Dean's answer may be the way forward (and is similar to this stackoverflow answer on the subject: https://stackoverflow.com/a/19743026).
not sure what the issue is with b4a's sqrt method, but it you want java's sqrt() from java.lang.Math, you can do what's in the attached.
Both yield the same result.
Neither work on BigDecimal

#### Mahares

##### Expert
Longtime User
Neither work on BigDecimal
Dies the example in Post#2 work on BigDecimal?

#### OliverA

##### Expert
Longtime User
Dies the example in Post#2 work on BigDecimal?
It would need to be rewritten to use BigDecimal numbers instead of Double's. BTW, I was somewhat incorrect in stating that @drgottjr would not work on BigDecimal. What it does is convert a BigDecimal to Double and then use the sqrt method of the math library. Ok, that works, but defeats the whole purpose of BigDecimal, since for really big numbers, even Double becomes very imprecise.

#### drgottjr

##### Expert
Longtime User
sigh. apparently java's sqrt() of a bigdecimal doesn't work until java 9. passing a bigdecimal's.doublevalue to sqrt() may or may not accomplish anything special. in other words, the sqrt() of a bigdecimal isn't in the library because it didn't exist. there are numerous formulae around, like what appears above where you can set your scale of precision. sorry i poke my nose in.

#### drgottjr

##### Expert
Longtime User
i changed my mind. see if this works for you:

B4X:
``````'put this in main:
Dim jo as JavaObject
jo.initializeContext
Dim scale As Int = 200        ' scale to fit
dim somebigdecimal as string = "4"       ' put your bigdecimal here
Dim bdstring As String = jo.RunMethod("bdsqrt", Array(somebigdecimal,scale))
Log(bdstring)

'=========================================================

#if Java
import java.lang.Math;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;

public static String bdsqrt(String strparam, int SCALE) {
BigDecimal A = new BigDecimal( strparam );
final BigDecimal TWO = BigDecimal.valueOf(2);
BigDecimal x0 = new BigDecimal("0");
BigDecimal x1 = new BigDecimal(Math.sqrt(A.doubleValue()));
while (!x0.equals(x1)) {
x0 = x1;
x1 = A.divide(x0, SCALE, 4);
x1 = x1.divide(TWO, SCALE, 4);
}

return x1.toPlainString();
}
#End If``````

i found the function on stackoverflow. had to modify entry and exit to get it to work with b4x (the library's bigdecimal is not the same as java's, and i didn't want to spend the time modifying the code even more). the actual heavy work is exactly as found. it gave me answers i was expecting in the few tests i ran.

#### emexes

##### Expert
sorry i poke my nose in.
Hey, you've delivered up enough great solutions in the past to get you a free pass on delivering a close-but-no-cigar one here.

#### drgottjr

##### Expert
Longtime User
sqrt, primes, etc. not my thing. i can connect b4x with java for those who cannot, so i thought i could help in that way. still unclear. we'll see if originator chimes in. thanks anyway

#### agraham

##### Expert
Longtime User
The library's bigdecimal is not the same as java's
It is!
Java:
``````import java.math.BigDecimal;
import java.math.BigInteger;
//....
public BigDecimal bigd;``````
But it is wrapped. You can get /set the BigDecimal instance from the bigd field which could tidy your Java up a bit.

EDIT: BigInteger is also wrapped and has a corresponding bigi field

Last edited:

##### Member
Longtime User
Hello

In general x^y can be expressed as exp(yln(x)).
Now you can express your sqrt, set y=0.5, as exp (0.5 ln(x))
I don't know about the following errors of ln and exp computation

Replies
9
Views
2K
Replies
1
Views
812
Replies
1
Views
3K
Replies
1
Views
1K
B4A Library BigNumbers library
Replies
20
Views
15K