Skip to content

Commit a68916b

Browse files
Leonardo Cicconildcicconi
authored andcommitted
added Sqrt and SqrtRound functions
1 parent f77bb07 commit a68916b

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

decimal.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
13631409
func min(x, y int32) int32 {
13641410
if x >= y {
13651411
return y

0 commit comments

Comments
 (0)