From 0a2095ccac88b2974ccda3cf536833de3ad4263b Mon Sep 17 00:00:00 2001 From: tompng Date: Fri, 22 Aug 2025 00:52:08 +0900 Subject: [PATCH] Fix x.fix and x.frac affected by prec limit, Stop -x and x.abs round with prec limit --- ext/bigdecimal/bigdecimal.c | 12 ++++++------ test/bigdecimal/test_bigdecimal.rb | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 0722e150..010a783f 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -1702,8 +1702,8 @@ static VALUE BigDecimal_neg(VALUE self) { BDVALUE a = GetBDValueMust(self); - BDVALUE c = NewZeroWrapLimited(1, a.real->Prec * BASE_FIG); - VpAsgn(c.real, a.real, -1); + BDVALUE c = NewZeroWrapNolimit(1, a.real->Prec * BASE_FIG); + VpAsgn(c.real, a.real, -10); RB_GC_GUARD(a.bigdecimal); return CheckGetValue(c); } @@ -2176,8 +2176,8 @@ static VALUE BigDecimal_abs(VALUE self) { BDVALUE a = GetBDValueMust(self); - BDVALUE c = NewZeroWrapLimited(1, a.real->Prec * BASE_FIG); - VpAsgn(c.real, a.real, 1); + BDVALUE c = NewZeroWrapNolimit(1, a.real->Prec * BASE_FIG); + VpAsgn(c.real, a.real, 10); VpChangeSign(c.real, 1); RB_GC_GUARD(a.bigdecimal); return CheckGetValue(c); @@ -2215,7 +2215,7 @@ static VALUE BigDecimal_fix(VALUE self) { BDVALUE a = GetBDValueMust(self); - BDVALUE c = NewZeroWrapLimited(1, (a.real->Prec + 1) * BASE_FIG); + BDVALUE c = NewZeroWrapNolimit(1, (a.real->Prec + 1) * BASE_FIG); VpActiveRound(c.real, a.real, VP_ROUND_DOWN, 0); /* 0: round off */ RB_GC_GUARD(a.bigdecimal); return CheckGetValue(c); @@ -2359,7 +2359,7 @@ static VALUE BigDecimal_frac(VALUE self) { BDVALUE a = GetBDValueMust(self); - BDVALUE c = NewZeroWrapLimited(1, (a.real->Prec + 1) * BASE_FIG); + BDVALUE c = NewZeroWrapNolimit(1, (a.real->Prec + 1) * BASE_FIG); VpFrac(c.real, a.real); RB_GC_GUARD(a.bigdecimal); return CheckGetValue(c); diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index 636d2622..0fdfd7c9 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -2051,6 +2051,31 @@ def test_div_mod_rem_operation_with_limit end end + def test_sign_operator_ignores_limit + plus_x = BigDecimal('7' * 100) + minus_x = -plus_x + BigDecimal.save_limit do + BigDecimal.limit(3) + assert_equal(plus_x, +plus_x) + assert_equal(minus_x, +minus_x) + assert_equal(minus_x, -plus_x) + assert_equal(plus_x, -minus_x) + assert_equal(plus_x, minus_x.abs) + assert_equal(plus_x, plus_x.abs) + end + end + + def test_fix_frac_ignores_limit + fix = BigDecimal("#{'4' * 56}") + frac = BigDecimal("0.#{'7' * 89}") + x = fix + frac + BigDecimal.save_limit do + BigDecimal.limit(3) + assert_equal(fix, x.fix) + assert_equal(frac, x.frac) + end + end + def test_sign BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)