gmpy icon indicating copy to clipboard operation
gmpy copied to clipboard

mpfr ignores context

Open cdonovick opened this issue 5 years ago • 2 comments

When constructing a mpfr from an mpfr the precision of the input is used not the context.

get_context().precision = 10
x = mpfr('0.3') # mpfr('0.2998',10)
get_context().precision = 5
y = mpfr(x) # mpfr('0.2998', 10)
y = mpfr(x, get_context().precision) # mpfr('0.297', 5)

This behavior if not a bug is definitely undocumented

cdonovick avatar May 22 '19 19:05 cdonovick

The behavior you are seeing is the desired behavior -- by default, mpfr() and mpc() should convert exactly if possible.This changes the rules around conversion but should reduce errors due to accidental double-rounding. The decimal module already uses this approach.

Decimal converts floats exactly and ignores the precision of the context. The + operator is used to coerce a Decimal to match the context settings.

import decimal x=decimal.Decimal(1.23) x Decimal('1.229999999999999982236431605997495353221893310546875') +x Decimal('1.229999999999999982236431606')

Internally, gmpy2 should use a precision of 0 to imply "match the context" and a precision of "1" to imply "convert exactly if possible, otherwise match the context". Exact conversion is already used when automatically converting operands.

Unfortunately, the actual implementation wasn't ready so the change was unexpected. I will review the implementation and update the documentation.

casevh avatar Jul 17 '19 05:07 casevh

I'm planning to make the following change in 2.1.0.b4:

  1. If possible, mpfr and mpc conversions will be done exactly.
  2. If the precision of the result is less than the precision of the active context, the precision will be increased to match the precision of the context.

I chose step 2 to avoid creating unexpectedly low precision values for mpfr(1). While technically valid, I think it would cause too much confusion.

casevh avatar Aug 26 '19 05:08 casevh