Bug #17264


BigDecimal exponentiation cannot be used with #** method

Added by karatedog (Földes László) 7 months ago. Updated 5 months ago.

Target version:
ruby -v:
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]


As stated in Bug #17214 ( when exponentiating a BigDdecimal number even when using small numbers, a precision argument must be passed to the operation or the operation will return wrong result, 2222 and 3.5 not being 'huge' numbers:

(BigDecimal("2222",10000) ** BigDecimal("3.5",10000)).to_i
# => 517135311000

However the #** method cannot be passed a precision argument and as seen above it will return wrong values for small numbers even if the BigDecimal numbers themselves have a large precision argument.
Therefore this operation can only be valid if used with the #power method and provided with a larger precision argument:

BigDecimal(2222).power(3.5, 15).to_i #=> 517135308457

My suggestion is the #** method and #power method should work the same way or the #** method retired.

Updated by jeremyevans0 (Jeremy Evans) 6 months ago

  • Assignee set to mrkn (Kenta Murata)
  • Status changed from Open to Assigned

karatedog (Földes László) wrote:

My suggestion is the #** method and #power method should work the same way or the #** method retired.

The methods actually do operate the same way. #** is basically:

def **(other)

So the issue is basically the precision for power when given one argument is not high enough, at least for fractional powers. I've submitted a pull request to increase the precision, but the downside is it makes the power calculations much slower: It is up to mrkn (Kenta Murata) whether the benefits of increasing the precision are worth the performance decrease.

Actions #2

Updated by Anonymous 5 months ago

  • Status changed from Assigned to Closed

Applied in changeset git|a86c147579745859ea064ec22b2901a7ac7e4abf.

Import bigdecimal 2.0.2 (#3905)

  • remove duplicated include

  • Make BigDecimal#round with argument < 1 return Integer

Fixes [Bug #12780]

  • Use a higher default precision for BigDecimal#power and #**

When a fractional power is given, increase the precision if the
precision isn't specified via power's second argument:

Float: increase by 15 (rough number of decimal precision in float)
BigDecimal: increase by adding similar precision modifier as done to
calculate the base precision.
Rational: double the precision, since a BigDecimal is created, but
the created BigDecimal uses the same precision.

Increasing the precision for these power calculations has the obvious
tradeoff of making the calculations slower.

Fixes Ruby Bug #17264

  • Use DBLE_FIG for a Float value

  • Version 2.0.1

Co-authored-by: pavel
Co-authored-by: Jeremy Evans


Also available in: Atom PDF