Skip to content

Keep full precision when BigMath.exp receives a Rational - #572

Open
NopeCharon wants to merge 1 commit into
ruby:masterfrom
NopeCharon:exp_rational_precision
Open

NopeCharon wants to merge 1 commit into
ruby:masterfrom
NopeCharon:exp_rational_precision

Conversation

@NopeCharon

Copy link
Copy Markdown

BigMath.exp converted a Rational argument with BigDecimal(x, prec), which keeps only prec significant digits of x. exp turns the relative error of x into an absolute error of the result, so an argument with a k-digit integer part lost up to k digits of precision (first example in #444):

BigMath.exp(10**19/3r, 50).to_s[0,52]
#=> "0.31897971307307432918427098497346266668405585204999"
BigMath.exp(10**19/3r, 1000).to_s[0,52]
#=> "0.31897971307307432918427098497347329934115828786096"

A Rational is now converted with prec + max(exponent, 0) significant digits, as suggested in the issue. The TODO on coerce_to_bigdecimal is kept because log, sin and cos still need their own conversions.

Adds test_exp_rational, which fails without the change.

Refs #444 (only the BigMath.exp part)

BigMath.exp converted a Rational argument with BigDecimal(x, prec), which
only keeps prec significant digits of x. exp amplifies the relative error
of x into an absolute error of the result, so for an argument with an
integer part of k digits the result lost up to k digits of precision:

  BigMath.exp(10**19/3r, 50)   # wrong after 31 digits
  BigMath.exp(10**19/3r, 1000) # reference

Convert a Rational with prec + (number of integer digits) significant
digits instead. Add a test that checks the result converges to the
higher-precision value for large, small and negative Rationals.

Refs ruby#444

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant