From 3954520093794105dd12063d46c009be3af06a66 Mon Sep 17 00:00:00 2001 From: Geert van Kempen Date: Sun, 19 Aug 2018 10:54:18 -0400 Subject: [PATCH] native square root function for decimal --- numbers.go | 68 ++++++++++++++++++++++++++---------------------------- sqrt.go | 32 +++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 35 deletions(-) create mode 100644 sqrt.go diff --git a/numbers.go b/numbers.go index 2a92469..d4e407e 100644 --- a/numbers.go +++ b/numbers.go @@ -1,99 +1,97 @@ -package common - -import "github.com/shopspring/decimal" +package decimal // MinusOne defines value -1 in decimal format -var MinusOne = decimal.New(-1, 0) +var MinusOne = New(-1, 0) // OneTenth defines value 0.1 in decimal format -var OneTenth = decimal.New(1, -1) +var OneTenth = New(1, -1) // TwoTenth defines value 0.1 in decimal format -var TwoTenth = decimal.New(2, -1) +var TwoTenth = New(2, -1) // Half defines value 0.5 in decimal format -var Half = decimal.New(5, -1) +var Half = New(5, -1) // One defines value 1 in decimal format -var One = decimal.New(1, 0) +var One = New(1, 0) // Two defines value 2 in decimal format -var Two = decimal.New(2, 0) +var Two = New(2, 0) // Three defines value 3 in decimal format -var Three = decimal.New(3, 0) +var Three = New(3, 0) // Four defines value 4 in decimal format -var Four = decimal.New(4, 0) +var Four = New(4, 0) // Five defines value 5 in decimal format -var Five = decimal.New(5, 0) +var Five = New(5, 0) // Six defines value 6 in decimal format -var Six = decimal.New(6, 0) +var Six = New(6, 0) // Seven defines value 6 in decimal format -var Seven = decimal.New(7, 0) +var Seven = New(7, 0) // Eight defines value 8 in decimal format -var Eight = decimal.New(8, 0) +var Eight = New(8, 0) // Nine defines value 9 in decimal format -var Nine = decimal.New(9, 0) +var Nine = New(9, 0) // Ten defines value 10 in decimal format -var Ten = decimal.New(10, 0) +var Ten = New(10, 0) // Twenty defines value 20 in decimal format -var Twenty = decimal.New(20, 0) +var Twenty = New(20, 0) // Thirty defines value 30 in decimal format -var Thirty = decimal.New(30, 0) +var Thirty = New(30, 0) // Forty defines value 40 in decimal format -var Forty = decimal.New(40, 0) +var Forty = New(40, 0) // Fifty defines value 50 in decimal format -var Fifty = decimal.New(50, 0) +var Fifty = New(50, 0) // Sixty defines value 60 in decimal format -var Sixty = decimal.New(60, 0) +var Sixty = New(60, 0) // Seventy defines value 70 in decimal format -var Seventy = decimal.New(70, 0) +var Seventy = New(70, 0) // Eighty defines value 80 in decimal format -var Eighty = decimal.New(80, 0) +var Eighty = New(80, 0) // Ninty defines value 90 in decimal format -var Ninty = decimal.New(90, 0) +var Ninty = New(90, 0) // Hundred defines value 100 in decimal format -var Hundred = decimal.New(100, 0) +var Hundred = New(100, 0) // TwoHundred defines value 200 in decimal format -var TwoHundred = decimal.New(200, 0) +var TwoHundred = New(200, 0) // ThreeHundred defines value 300 in decimal format -var ThreeHundred = decimal.New(300, 0) +var ThreeHundred = New(300, 0) // FourHundred defines value 400 in decimal format -var FourHundred = decimal.New(400, 0) +var FourHundred = New(400, 0) // FiveHundred defines value 500 in decimal format -var FiveHundred = decimal.New(500, 0) +var FiveHundred = New(500, 0) // SixHundred defines value 600 in decimal format -var SixHundred = decimal.New(600, 0) +var SixHundred = New(600, 0) // SevenHundred defines value 700 in decimal format -var SevenHundred = decimal.New(700, 0) +var SevenHundred = New(700, 0) // EightHundred defines value 800 in decimal format -var EightHundred = decimal.New(800, 0) +var EightHundred = New(800, 0) // NineHundred defines value 900 in decimal format -var NineHundred = decimal.New(900, 0) +var NineHundred = New(900, 0) // Thousand defines value 100 in decimal format -var Thousand = decimal.New(1000, 0) +var Thousand = New(1000, 0) diff --git a/sqrt.go b/sqrt.go new file mode 100644 index 0000000..804586c --- /dev/null +++ b/sqrt.go @@ -0,0 +1,32 @@ +package decimal + +const sqrtMaxIter = 10000 + +// Sqrt returns the square root of d, the result will have +// DivisionPrecision digits after the decimal point. +func (d Decimal) Sqrt() Decimal { + s, _ := d.SqrtRound(int32(DivisionPrecision)) + return s +} + +// SqrtRound returns the square root of d, the result will have +// precision digits after the decimal point. The bool precise returns whether the precision was reached +func (d Decimal) SqrtRound(precision int32) (Decimal, bool) { + cutoff := New(1, -precision) + lo := Zero + hi := d + var mid Decimal + for i := 0; i < sqrtMaxIter; i++ { + //mid = (lo+hi)/2; + mid = lo.Add(hi).DivRound(Two, precision) + if mid.Mul(mid).Sub(d).Abs().LessThan(cutoff) { + return mid, true + } + if mid.Mul(mid).GreaterThan(d) { + hi = mid + } else { + lo = mid + } + } + return mid, false +}