@@ -1360,6 +1360,52 @@ func RescalePair(d1 Decimal, d2 Decimal) (Decimal, Decimal) {
13601360 return d1 , d2 .rescale (baseScale )
13611361}
13621362
1363+ // SqrtMaxIter sets a limit for number of iterations for the Sqrt function
1364+ const SqrtMaxIter = 100000
1365+
1366+ // Sqrt returns the square root of d, accurate to DivisionPrecision decimal places.
1367+ func Sqrt (d Decimal ) Decimal {
1368+ s , _ := SqrtRound (d , int32 (DivisionPrecision ))
1369+ return s
1370+ }
1371+
1372+ // SqrtRound returns the square root of d, accurate to precision decimal places.
1373+ // The bool precise returns whether the precision was reached.
1374+ func SqrtRound (d Decimal , precision int32 ) (Decimal , bool ) {
1375+ maxError := New (1 , - precision )
1376+ one := NewFromFloat (1 )
1377+ var lo Decimal
1378+ var hi Decimal
1379+ // Handle cases where d < 0, d = 0, 0 < d < 1, and d > 1
1380+ if d .GreaterThanOrEqual (one ) {
1381+ lo = Zero
1382+ hi = d
1383+ } else if d .Equal (one ) {
1384+ return one , true
1385+ } else if d .LessThan (Zero ) {
1386+ return NewFromFloat (- 1 ), false // call this an error , cannot take sqrt of neg w/o imaginaries
1387+ } else if d .Equal (Zero ) {
1388+ return Zero , true
1389+ } else {
1390+ // d is between 0 and 1. Therefore, 0 < d < Sqrt(d) < 1.
1391+ lo = d
1392+ hi = one
1393+ }
1394+ var mid Decimal
1395+ for i := 0 ; i < SqrtMaxIter ; i ++ {
1396+ mid = lo .Add (hi ).Div (New (2 , 0 )) //mid = (lo+hi)/2;
1397+ if mid .Mul (mid ).Sub (d ).Abs ().LessThan (maxError ) {
1398+ return mid , true
1399+ }
1400+ if mid .Mul (mid ).GreaterThan (d ) {
1401+ hi = mid
1402+ } else {
1403+ lo = mid
1404+ }
1405+ }
1406+ return mid , false
1407+ }
1408+
13631409func min (x , y int32 ) int32 {
13641410 if x >= y {
13651411 return y
0 commit comments