From 5ec56358e549507251fdd72f4982554f52af6e7d Mon Sep 17 00:00:00 2001 From: Jason Biegel Date: Tue, 10 Dec 2019 00:51:18 -0500 Subject: [PATCH 1/2] revert original remove insignificant change (PR 46), and add the logic back as a function --- decimal.go | 13 +++++-------- decimal_test.go | 26 ++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/decimal.go b/decimal.go index 7a67c8c0..aac42428 100644 --- a/decimal.go +++ b/decimal.go @@ -153,13 +153,8 @@ func NewFromString(value string) (Decimal, error) { // an int intString = value } else if len(parts) == 2 { - // strip the insignificant digits for more accurate comparisons. - decimalPart := strings.TrimRight(parts[1], "0") - intString = parts[0] + decimalPart - if intString == "" && parts[1] != "" { - intString = "0" - } - expInt := -len(decimalPart) + intString = parts[0] + parts[1] + expInt := -len(parts[1]) exp += int64(expInt) } else { return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value) @@ -852,6 +847,7 @@ func (d Decimal) RoundBank(places int32) Decimal { // 100: 100 cent rounding 3.50 => 4.00 // For more details: https://en.wikipedia.org/wiki/Cash_rounding func (d Decimal) RoundCash(interval uint8) Decimal { + iD := d.RemoveInsignificantDigits() var iVal *big.Int switch interval { case 5: @@ -870,8 +866,9 @@ func (d Decimal) RoundCash(interval uint8) Decimal { dVal := Decimal{ value: iVal, } + // TODO: optimize those calculations to reduce the high allocations (~29 allocs). - return d.Mul(dVal).Round(0).Div(dVal).Truncate(2) + return iD.Mul(dVal).Round(0).Div(dVal).Truncate(2) } // Floor returns the nearest integer value less than or equal to d. diff --git a/decimal_test.go b/decimal_test.go index 43a51bf5..301901fc 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -310,8 +310,9 @@ func TestNewFromStringDeepEquals(t *testing.T) { } tests := []StrCmp{ {"1", "1", true}, - {"10", "10.0", true}, - {"1.1", "1.10", true}, + {"1.0", "1.0", true}, + {"10", "10.0", false}, + {"1.1", "1.10", false}, {"1.001", "1.01", false}, } @@ -2489,6 +2490,27 @@ func TestTan(t *testing.T) { } } +func TestRemoveInsignificantDigits(t *testing.T) { + cases := []struct { + input Decimal + expectedResult Decimal + }{ + {New(1, 0), New(1, 0)}, + {New(10, 0), New(1, 1)}, + {New(10, -1), New(1, 0)}, + {New(10, 1), New(10, 1)}, + } + for _, s := range cases { + actualResult := s.input.RemoveInsignificantDigits() + if !reflect.DeepEqual(s.expectedResult, actualResult) { + t.Errorf("with %se%d, expected %se%d, got %se%d", + s.input.value, s.input.exp, + s.expectedResult.value, s.expectedResult.exp, + actualResult.value, actualResult.exp) + } + } +} + func ExampleNewFromFloat32() { fmt.Println(NewFromFloat32(123.123123123123).String()) fmt.Println(NewFromFloat32(.123123123123123).String()) From b4bac45bdd123a3c6926f6c11cd343c0a392d8f1 Mon Sep 17 00:00:00 2001 From: Jason Biegel Date: Tue, 25 Feb 2020 19:55:44 -0500 Subject: [PATCH 2/2] remove RoundCash changes and RemoveInsignificantDigits --- decimal.go | 3 +-- decimal_test.go | 21 --------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/decimal.go b/decimal.go index aac42428..b78581b7 100644 --- a/decimal.go +++ b/decimal.go @@ -847,7 +847,6 @@ func (d Decimal) RoundBank(places int32) Decimal { // 100: 100 cent rounding 3.50 => 4.00 // For more details: https://en.wikipedia.org/wiki/Cash_rounding func (d Decimal) RoundCash(interval uint8) Decimal { - iD := d.RemoveInsignificantDigits() var iVal *big.Int switch interval { case 5: @@ -868,7 +867,7 @@ func (d Decimal) RoundCash(interval uint8) Decimal { } // TODO: optimize those calculations to reduce the high allocations (~29 allocs). - return iD.Mul(dVal).Round(0).Div(dVal).Truncate(2) + return d.Mul(dVal).Round(0).Div(dVal).Truncate(2) } // Floor returns the nearest integer value less than or equal to d. diff --git a/decimal_test.go b/decimal_test.go index 301901fc..c6843355 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -2490,27 +2490,6 @@ func TestTan(t *testing.T) { } } -func TestRemoveInsignificantDigits(t *testing.T) { - cases := []struct { - input Decimal - expectedResult Decimal - }{ - {New(1, 0), New(1, 0)}, - {New(10, 0), New(1, 1)}, - {New(10, -1), New(1, 0)}, - {New(10, 1), New(10, 1)}, - } - for _, s := range cases { - actualResult := s.input.RemoveInsignificantDigits() - if !reflect.DeepEqual(s.expectedResult, actualResult) { - t.Errorf("with %se%d, expected %se%d, got %se%d", - s.input.value, s.input.exp, - s.expectedResult.value, s.expectedResult.exp, - actualResult.value, actualResult.exp) - } - } -} - func ExampleNewFromFloat32() { fmt.Println(NewFromFloat32(123.123123123123).String()) fmt.Println(NewFromFloat32(.123123123123123).String())