From 32b6fb18914604f87e050109c4aa77ba44c857c0 Mon Sep 17 00:00:00 2001 From: "William T. Nelson" <35801+wtn@users.noreply.github.com> Date: Sat, 14 Nov 2026 12:17:17 -0600 Subject: [PATCH] Fix round(n, :up) returning 0 for some nonzero values BigDecimal stores digits in groups of nine and skips leading all-zero groups, so the first group of 1e-10 begins at the 10th decimal place. When the rounding position fell before the first group, :up truncated to 0: BigDecimal("1e-10").round(0, :up) returned 0 instead of 1. Co-authored-by: Claude Opus 5.5 --- ext/bigdecimal/bigdecimal.c | 2 +- test/bigdecimal/test_bigdecimal.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 2c28e13a..e1b9f6e4 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -5889,7 +5889,7 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf) exptoadd=0; if (nf < 0) { /* rounding position too left(large). */ - if (f != VP_ROUND_CEIL && f != VP_ROUND_FLOOR) { + if (f != VP_ROUND_UP && f != VP_ROUND_CEIL && f != VP_ROUND_FLOOR) { VpSetZero(y, VpGetSign(y)); /* truncate everything */ return 0; } diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index fe92ecdf..502d9345 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -1541,6 +1541,10 @@ def test_round assert_equal(x.round(0, const), x.round(0, sym)) end + assert_equal(1, BigDecimal("1e-10").round(0, BigDecimal::ROUND_UP)) + assert_equal(-1, BigDecimal("-1e-10").round(0, BigDecimal::ROUND_UP)) + assert_equal(10**10, BigDecimal("5").round(-10, BigDecimal::ROUND_UP)) + bug3803 = '[ruby-core:32136]' 15.times do |n| x = BigDecimal("5#{'0'*n}1")