From 0f927d00acfa2d48591368a8d1bcfa6153285b1a Mon Sep 17 00:00:00 2001 From: mwoss Date: Fri, 29 Dec 2023 01:56:26 +0100 Subject: [PATCH] Fix incorrect calculation of const precision, add tests --- const.go | 12 +++++++----- const_test.go | 34 ++++++++++++++++++++++++++++++++++ decimal_test.go | 2 +- 3 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 const_test.go diff --git a/const.go b/const.go index 237846a..9417201 100644 --- a/const.go +++ b/const.go @@ -26,7 +26,7 @@ func newConstApproximation(value string) constApproximation { var approximations []Decimal for p := 1; p < maxPrecision; p *= 2 { - r := RequireFromString(strLn10[:coeffLen+p]) + r := RequireFromString(value[:coeffLen+p]) approximations = append(approximations, r) } @@ -36,13 +36,15 @@ func newConstApproximation(value string) constApproximation { } } -// Returns the smallest approximation available that's at least as precise as the passed precision -// i.e. Ceil[ log2(precision) ] = 1 + Floor[ log2(precision-1) ] +// Returns the smallest approximation available that's at least as precise +// as the passed precision (places after decimal point), i.e. Floor[ log2(precision) ] + 1 func (c constApproximation) withPrecision(precision int32) Decimal { i := 0 - if precision > 1 { - precision-- + // 0, 1, 2-3, 4-7, 8-15, 16-31, 32-63 + // 0, 1, 2, 3, 4, 5, 6 + + if precision >= 1 { i++ } diff --git a/const_test.go b/const_test.go new file mode 100644 index 0000000..67a27a7 --- /dev/null +++ b/const_test.go @@ -0,0 +1,34 @@ +package decimal + +import "testing" + +func TestConstApproximation(t *testing.T) { + for _, testCase := range []struct { + Const string + Precision int32 + ExpectedApproximation string + }{ + {"2.3025850929940456840179914546", 0, "2"}, + {"2.3025850929940456840179914546", 1, "2.3"}, + {"2.3025850929940456840179914546", 3, "2.302"}, + {"2.3025850929940456840179914546", 5, "2.302585"}, + {"2.3025850929940456840179914546", 10, "2.302585092994045"}, + {"2.3025850929940456840179914546", 100, "2.3025850929940456840179914546"}, + {"2.3025850929940456840179914546", -1, "2"}, + {"2.3025850929940456840179914546", -5, "2"}, + {"3.14159265359", 0, "3"}, + {"3.14159265359", 1, "3.1"}, + {"3.14159265359", 2, "3.141"}, + {"3.14159265359", 4, "3.1415926"}, + {"3.14159265359", 13, "3.14159265359"}, + } { + ca := newConstApproximation(testCase.Const) + expected, _ := NewFromString(testCase.ExpectedApproximation) + + approximation := ca.withPrecision(testCase.Precision) + + if approximation.Cmp(expected) != 0 { + t.Errorf("expected approximation %s, got %s - for const with %s precision %d", testCase.ExpectedApproximation, approximation.String(), testCase.Const, testCase.Precision) + } + } +} diff --git a/decimal_test.go b/decimal_test.go index 29454b9..2df9591 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -2774,7 +2774,7 @@ func TestDecimal_Ln(t *testing.T) { {"839101.0351", 25, "13.6400864014410013994397240"}, {"839101.0351094726488848490572028502", 50, "13.64008640145229044389152437468283605382056561604272"}, {"5023583755703750094849.03519358513093500275017501750602739169823", 25, "49.9684305274348922267409953"}, - {"5023583755703750094849.03519358513093500275017501750602739169823", -1, "40.0"}, + {"5023583755703750094849.03519358513093500275017501750602739169823", -1, "50.0"}, } { d, _ := NewFromString(testCase.Dec) expected, _ := NewFromString(testCase.Expected)