From 70eaa6c75d0fce7048eb7d6a4e11b651f8ddbdd3 Mon Sep 17 00:00:00 2001 From: kempeng <39567537+kempeng@users.noreply.github.com> Date: Wed, 25 Jul 2018 23:19:28 -0400 Subject: [PATCH 1/5] Create helpers.go helpers.go defines several helper functions for the create of new decimal's from int's that make code using decimal a bit easier to read. Further more it implements a.Max() and a.Min() functions in the same fashion as other arithmetic functions like Add & Sub. (the decimal package already implements Max(d, d2....) and Min(), but these two helper functions are complementary to them. Finally a.Float() is a convenience function for a.Float64() that ignore the precise bool, allowing inline use of the float conversion function --- helpers.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 helpers.go diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..954f001 --- /dev/null +++ b/helpers.go @@ -0,0 +1,38 @@ +package decimal + +// Float returns the decimal value as a float64 +// float is a helper function for float64() and doesnot return bool exact +func (d Decimal) Float() float64 { + f, _ := d.Float64() + return f +} + +// NotEqual returns true when d is not equal to d2 +func (d Decimal) NotEqual(d2 Decimal) bool { + return !d.Equal(d2) +} + +// Max returns the maximum value between d and d2 +func (d Decimal) Max(d2 Decimal) Decimal { + return Max(d, d2) +} + +// Min returns the minimum value between d and d2 +func (d Decimal) Min(d2 Decimal) Decimal { + return Min(d, d2) +} + +//NewFromInt returns a decimal with the value of int v +func NewFromInt(v int) Decimal { + return New(int64(v), 0) +} + +//NewFromInt32 returns a decimal with the value of int v +func NewFromInt32(v int) Decimal { + return New(int64(v), 0) +} + +//NewFromInt64 returns a decimal with the value of int v +func NewFromInt64(v int64) Decimal { + return New(v, 0) +} From e20cd0e503e47e37db1f9bf382b3543039adc100 Mon Sep 17 00:00:00 2001 From: kempeng <39567537+kempeng@users.noreply.github.com> Date: Wed, 25 Jul 2018 23:22:11 -0400 Subject: [PATCH 2/5] Create zero.go Zero.go defines convenience functions for testing decimal values with the zero value. These functions make code using decimal easier to read in my opinion. EqualZero() could be renamed into IsZero() --- zero.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 zero.go diff --git a/zero.go b/zero.go new file mode 100644 index 0000000..132d135 --- /dev/null +++ b/zero.go @@ -0,0 +1,31 @@ +package decimal + +// EqualZero returns whether the numbers represented by d equals zero. +func (d Decimal) EqualZero() bool { + return d.Equal(Zero) +} + +// NotZero returns whether d is not zero +func (d Decimal) NotZero() bool { + return !d.EqualZero() +} + +// GreaterThanZero (GT0) returns true when d is greater than zero. +func (d Decimal) GreaterThanZero() bool { + return d.GreaterThan(Zero) +} + +// GreaterThanOrEqualZero (GTE0) returns true when d is greater than or equal to zero. +func (d Decimal) GreaterThanOrEqualZero() bool { + return d.GreaterThanOrEqual(Zero) +} + +// LessThanZero returns true when d is less than zero. +func (d Decimal) LessThanZero() bool { + return d.LessThan(Zero) +} + +// LessThanOrEqualZero returns true when d is less than or equal to zero. +func (d Decimal) LessThanOrEqualZero() bool { + return d.LessThanOrEqual(Zero) +} From 53965de0863676470b02a1726993ac9d0b39bb56 Mon Sep 17 00:00:00 2001 From: Geert van Kempen Date: Sun, 19 Aug 2018 10:44:32 -0400 Subject: [PATCH 3/5] additional decimal numbers --- numbers.go | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 numbers.go diff --git a/numbers.go b/numbers.go new file mode 100644 index 0000000..2a92469 --- /dev/null +++ b/numbers.go @@ -0,0 +1,99 @@ +package common + +import "github.com/shopspring/decimal" + +// MinusOne defines value -1 in decimal format +var MinusOne = decimal.New(-1, 0) + +// OneTenth defines value 0.1 in decimal format +var OneTenth = decimal.New(1, -1) + +// TwoTenth defines value 0.1 in decimal format +var TwoTenth = decimal.New(2, -1) + +// Half defines value 0.5 in decimal format +var Half = decimal.New(5, -1) + +// One defines value 1 in decimal format +var One = decimal.New(1, 0) + +// Two defines value 2 in decimal format +var Two = decimal.New(2, 0) + +// Three defines value 3 in decimal format +var Three = decimal.New(3, 0) + +// Four defines value 4 in decimal format +var Four = decimal.New(4, 0) + +// Five defines value 5 in decimal format +var Five = decimal.New(5, 0) + +// Six defines value 6 in decimal format +var Six = decimal.New(6, 0) + +// Seven defines value 6 in decimal format +var Seven = decimal.New(7, 0) + +// Eight defines value 8 in decimal format +var Eight = decimal.New(8, 0) + +// Nine defines value 9 in decimal format +var Nine = decimal.New(9, 0) + +// Ten defines value 10 in decimal format +var Ten = decimal.New(10, 0) + +// Twenty defines value 20 in decimal format +var Twenty = decimal.New(20, 0) + +// Thirty defines value 30 in decimal format +var Thirty = decimal.New(30, 0) + +// Forty defines value 40 in decimal format +var Forty = decimal.New(40, 0) + +// Fifty defines value 50 in decimal format +var Fifty = decimal.New(50, 0) + +// Sixty defines value 60 in decimal format +var Sixty = decimal.New(60, 0) + +// Seventy defines value 70 in decimal format +var Seventy = decimal.New(70, 0) + +// Eighty defines value 80 in decimal format +var Eighty = decimal.New(80, 0) + +// Ninty defines value 90 in decimal format +var Ninty = decimal.New(90, 0) + +// Hundred defines value 100 in decimal format +var Hundred = decimal.New(100, 0) + +// TwoHundred defines value 200 in decimal format +var TwoHundred = decimal.New(200, 0) + +// ThreeHundred defines value 300 in decimal format +var ThreeHundred = decimal.New(300, 0) + +// FourHundred defines value 400 in decimal format +var FourHundred = decimal.New(400, 0) + +// FiveHundred defines value 500 in decimal format +var FiveHundred = decimal.New(500, 0) + +// SixHundred defines value 600 in decimal format +var SixHundred = decimal.New(600, 0) + +// SevenHundred defines value 700 in decimal format +var SevenHundred = decimal.New(700, 0) + +// EightHundred defines value 800 in decimal format +var EightHundred = decimal.New(800, 0) + +// NineHundred defines value 900 in decimal format +var NineHundred = decimal.New(900, 0) + +// Thousand defines value 100 in decimal format +var Thousand = decimal.New(1000, 0) From 3954520093794105dd12063d46c009be3af06a66 Mon Sep 17 00:00:00 2001 From: Geert van Kempen Date: Sun, 19 Aug 2018 10:54:18 -0400 Subject: [PATCH 4/5] 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 +} From aa8a681072d3e103f1c83d705787272628c2cf44 Mon Sep 17 00:00:00 2001 From: Geert van Kempen Date: Sun, 19 Aug 2018 14:00:50 -0400 Subject: [PATCH 5/5] added sqrt testing --- numbers.go | 27 +++++++++++++++++++++++++++ sqrt.go | 3 +++ sqrt_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 sqrt_test.go diff --git a/numbers.go b/numbers.go index d4e407e..ab8c01d 100644 --- a/numbers.go +++ b/numbers.go @@ -42,6 +42,33 @@ var Nine = New(9, 0) // Ten defines value 10 in decimal format var Ten = New(10, 0) +// Eleven defines value 11 in decimal format +var Eleven = New(11, 0) + +// Twelve defines value 12 in decimal format +var Twelve = New(12, 0) + +// Thirteen defines value 13 in decimal format +var Thirteen = New(13, 0) + +// Fourteen defines value 14 in decimal format +var Fourteen = New(14, 0) + +// Fifteen defines value 15 in decimal format +var Fifteen = New(15, 0) + +// Sixteen defines value 16 in decimal format +var Sixteen = New(16, 0) + +// Seventeen defines value 17 in decimal format +var Seventeen = New(17, 0) + +// Eighteen defines value 18 in decimal format +var Eighteen = New(18, 0) + +// Nineteen defines value 19 in decimal format +var Nineteen = New(19, 0) + // Twenty defines value 20 in decimal format var Twenty = New(20, 0) diff --git a/sqrt.go b/sqrt.go index 804586c..b0fb841 100644 --- a/sqrt.go +++ b/sqrt.go @@ -12,6 +12,9 @@ func (d Decimal) Sqrt() Decimal { // 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) { + if d.LessThanOrEqualZero() { + return Zero, false + } cutoff := New(1, -precision) lo := Zero hi := d diff --git a/sqrt_test.go b/sqrt_test.go new file mode 100644 index 0000000..7c1525e --- /dev/null +++ b/sqrt_test.go @@ -0,0 +1,24 @@ +package decimal + +import ( + "testing" +) + +func TestSqrt(t *testing.T) { + tables := []struct { + x Decimal + n Decimal + }{ + {One, One}, + {Four, Two}, + {Sixteen, Four}, + {Two, NewFromFloat(1.4142135623730951)}, + } + + for _, table := range tables { + result := table.x.Sqrt() + if result.NotEqual(table.n) { + t.Errorf("Sqrt of (%v) was incorrect, got: %v, want: %v.", table.x.String(), result.String(), table.n.String()) + } + } +}