From 85f19162ad1286d5053b827de704d9707c09cb0f Mon Sep 17 00:00:00 2001 From: troy Date: Mon, 10 Nov 2025 16:19:32 +0900 Subject: [PATCH 1/2] =?UTF-8?q?Handle=20Infinity=20base=20in=20power?= =?UTF-8?q?=E2=80=99s=20precision=20estimator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bigdecimal.rb | 2 +- test/bigdecimal/test_bigdecimal.rb | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/bigdecimal.rb b/lib/bigdecimal.rb index e9f8954b..7cdac655 100644 --- a/lib/bigdecimal.rb +++ b/lib/bigdecimal.rb @@ -197,7 +197,7 @@ def power(y, prec = 0) if x > 1 # To calculate exp(z, prec), z needs prec+max(z.exponent, 0) precision if z > 0. # Estimate (y*log(x)).exponent - logx_exponent = x < 2 ? (x - 1).exponent : Math.log10(x.exponent).round + logx_exponent = x < 2 ? (x - 1).exponent : Math.log10(x.exponent).then { _1.finite? ? _1.round : _1 } ylogx_exponent = y.exponent + logx_exponent prec2 += [ylogx_exponent, 0].max end diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index 35736b94..4f2ded4f 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -1851,10 +1851,16 @@ def test_power_of_positive_infinity assert_positive_infinite_calculation { BigDecimal::INFINITY ** 1.quo(1) } assert_positive_infinite_calculation { BigDecimal::INFINITY ** 1.0 } assert_positive_infinite_calculation { BigDecimal::INFINITY ** BigDecimal(1) } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 1.quo(2) } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 0.5 } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** BigDecimal(0.5) } assert_equal(1, BigDecimal::INFINITY ** 0) assert_equal(1, BigDecimal::INFINITY ** 0.quo(1)) assert_equal(1, BigDecimal::INFINITY ** 0.0) assert_equal(1, BigDecimal::INFINITY ** BigDecimal(0)) + assert_positive_zero(BigDecimal::INFINITY ** -1.quo(2)) + assert_positive_zero(BigDecimal::INFINITY ** -0.5) + assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-0.5)) assert_positive_zero(BigDecimal::INFINITY ** -1) assert_positive_zero(BigDecimal::INFINITY ** -1.quo(1)) assert_positive_zero(BigDecimal::INFINITY ** -1.0) From 758173dace48f854c1371d9de0d0198f8a421ff0 Mon Sep 17 00:00:00 2001 From: troy Date: Tue, 11 Nov 2025 11:08:57 +0900 Subject: [PATCH 2/2] Apply precision path only when x > 1 && x.finite? --- lib/bigdecimal.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bigdecimal.rb b/lib/bigdecimal.rb index 7cdac655..12250ce9 100644 --- a/lib/bigdecimal.rb +++ b/lib/bigdecimal.rb @@ -194,10 +194,10 @@ def power(y, prec = 0) end ans.mult(1, result_prec) else - if x > 1 + if x > 1 && x.finite? # To calculate exp(z, prec), z needs prec+max(z.exponent, 0) precision if z > 0. # Estimate (y*log(x)).exponent - logx_exponent = x < 2 ? (x - 1).exponent : Math.log10(x.exponent).then { _1.finite? ? _1.round : _1 } + logx_exponent = x < 2 ? (x - 1).exponent : Math.log10(x.exponent).round ylogx_exponent = y.exponent + logx_exponent prec2 += [ylogx_exponent, 0].max end