From 70bc8f338919aa6180d8bac8dda74a54fd04e1e6 Mon Sep 17 00:00:00 2001 From: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com> Date: Sun, 19 Jul 2026 14:53:28 -0700 Subject: [PATCH] fix: preserve totals when splitting rounded values Adjust the final allocation by the rounding remainder so proportional splits add back up to the requested total. Add a regression for three equal weights. --- percentify/stats.py | 3 +++ tests/test_stats.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/percentify/stats.py b/percentify/stats.py index 158f951..8741c31 100644 --- a/percentify/stats.py +++ b/percentify/stats.py @@ -892,6 +892,9 @@ def split(total, weights, decimals: Optional[int] = 2): shares = w.astype(float) / weight_sum * float(total) if decimals is not None: shares = shares.round(decimals) + remainder = round(float(total), decimals) - float(shares.sum()) + if remainder: + shares.iloc[-1] = round(shares.iloc[-1] + remainder, decimals) return shares if is_series else shares.tolist() diff --git a/tests/test_stats.py b/tests/test_stats.py index 7ac2e01..2b81393 100644 --- a/tests/test_stats.py +++ b/tests/test_stats.py @@ -609,7 +609,9 @@ def test_split_list(): def test_split_equal(): - assert split(100, [1, 1, 1]) == [pytest.approx(33.33)] * 3 + result = split(100, [1, 1, 1]) + assert result == [33.33, 33.33, 33.34] + assert sum(result) == 100 def test_split_series_returns_series():