From 4580a0392aa07d870d1cf915117214d5a8fae786 Mon Sep 17 00:00:00 2001 From: Sasha Mitchell Date: Wed, 30 Sep 2026 19:40:52 +0700 Subject: [PATCH] fix: round negative fractions toward zero math.Modf keeps the sign of the fractional part, so every negative value took math.Floor. round(-1.25, 0) returned -2. --- numeric.go | 4 ++++ numeric_test.go | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/numeric.go b/numeric.go index f68e4182..fda2499f 100644 --- a/numeric.go +++ b/numeric.go @@ -115,9 +115,13 @@ func round(a interface{}, p int, rOpt ...float64) float64 { var round float64 pow := math.Pow(10, places) digit := pow * val + // Modf keeps the sign of the fraction. A negative fraction below the + // threshold rounds toward zero, matching the positive side. _, div := math.Modf(digit) if div >= roundOn { round = math.Ceil(digit) + } else if div < 0 && div > -roundOn { + round = math.Ceil(digit) } else { round = math.Floor(digit) } diff --git a/numeric_test.go b/numeric_test.go index 1252cd73..5f1105e4 100644 --- a/numeric_test.go +++ b/numeric_test.go @@ -298,6 +298,15 @@ func TestRound(t *testing.T) { assert.Equal(t, 123.0, round(123.49999999, 0)) assert.Equal(t, 123.23, round(123.2329999, 2, .3)) assert.Equal(t, 123.24, round(123.233, 2, .3)) + // A negative fraction below the threshold rounds toward zero. + // -1.25 is exact in float64. Floor would return -2. + assert.Equal(t, -1.0, round(-1.25, 0)) + assert.Equal(t, -2.0, round(-1.5, 0)) + assert.Equal(t, -2.0, round(-1.75, 0)) + assert.Equal(t, -123.0, round(-123.49999999, 0)) + assert.Equal(t, -124.0, round(-123.500001, 0)) + assert.Equal(t, -123.23, round(-123.2329999, 2, .3)) + assert.Equal(t, -123.24, round(-123.233, 2, .3)) } func TestRandomInt(t *testing.T) {