From 2800b3c83cedceebe98d43f65e1bfab795a5576e Mon Sep 17 00:00:00 2001 From: Ryan Christoffersen <12519942+ryanchristo@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:40:44 -0700 Subject: [PATCH] fix(types): positive decimal from string must be finite (#1210) * fix(types): positive decimal from string must be finite * fix(types): positive decimal from string must be finite * add godocs and test * remove miscommit test files * update test per review comment --- types/math/dec.go | 10 +++++++++- types/math/dec_test.go | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/types/math/dec.go b/types/math/dec.go index 1ab6bec2fd..3da6c8f927 100644 --- a/types/math/dec.go +++ b/types/math/dec.go @@ -83,7 +83,7 @@ func NewPositiveDecFromString(s string) (Dec, error) { if err != nil { return Dec{}, ErrInvalidDecString.Wrap(err.Error()) } - if !d.IsPositive() { + if !d.IsPositive() || !d.IsFinite() { return Dec{}, ErrInvalidDecString.Wrapf("expected a positive decimal, got %s", s) } return d, nil @@ -246,18 +246,26 @@ func (x Dec) Equal(y Dec) bool { return x.dec.Cmp(&y.dec) == 0 } +// IsZero returns true if the decimal is zero. func (x Dec) IsZero() bool { return x.dec.IsZero() } +// IsNegative returns true if the decimal is negative. func (x Dec) IsNegative() bool { return x.dec.Negative && !x.dec.IsZero() } +// IsPositive returns true if the decimal is positive. func (x Dec) IsPositive() bool { return !x.dec.Negative && !x.dec.IsZero() } +// IsFinite returns true if the decimal is finite. +func (x Dec) IsFinite() bool { + return x.dec.Form == apd.Finite +} + // NumDecimalPlaces returns the number of decimal places in x. func (x Dec) NumDecimalPlaces() uint32 { exp := x.dec.Exponent diff --git a/types/math/dec_test.go b/types/math/dec_test.go index c02ce47f23..a799c5336e 100644 --- a/types/math/dec_test.go +++ b/types/math/dec_test.go @@ -598,6 +598,18 @@ func floatDecimalPlaces(t *rapid.T, f float64) uint32 { } } +func TestIsFinite(t *testing.T) { + a, err := NewDecFromString("1.5") + require.NoError(t, err) + + require.True(t, a.IsFinite()) + + b, err := NewDecFromString("NaN") + require.NoError(t, err) + + require.False(t, b.IsFinite()) +} + func TestReduce(t *testing.T) { a, err := NewDecFromString("1.30000") require.NoError(t, err)