Это ошибка в gmpy2 Python?

Простое сложение с плавающей точкой x+y с точностью 4 (т. Е. Ширина мантиссы IEEE 3), с показателем степени 3 бита (emax=3, emin=-4) за x = mpfr('0.75'), y = mpfr('0.03125') неправильно дает mpfr('0.75') как результат, когда это должно быть mpfr('0.8125'), Обратите внимание, что 0.3125 является ненормальным числом для этого формата с пониженной точностью.

Изменить: Терминальное взаимодействие извлечено из ссылки и включено для дальнейшего использования.

>>> "{0:.10Df}".format(mpfr('0.75')+mpfr('0.03125'))
'0.7500000000'
>>> get_context()
  context(precision=4, real_prec=Default, imag_prec=Default,
  round=RoundToNearest, real_round=Default, imag_round=Default,
  emax=3, emin=-4,
  subnormalize=True,
  trap_underflow=False, underflow=False,
  trap_overflow=False, overflow=False,
  trap_inexact=False, inexact=True,
  trap_invalid=False, invalid=False,
  trap_erange=False, erange=False,
  trap_divzero=False, divzero=False,
  trap_expbound=False,
  allow_complex=False)
>>>

1 ответ

Отказ от ответственности: я поддерживаю gmpy2.

Я считаю, что это ошибка с созданием субнормалей из строки. Я думаю, что это исправлено в коде разработки, но я не смогу проверить позже. Я обновлю этот ответ позже.

Обновить

Проблема не связана с созданием субнормального из строки. В этом случае субнормальное значение создается правильно. В gmpy2 2.0.x есть редкая ошибка при преобразовании строки в ненормальную. Самый простой обходной путь - преобразовать входные данные в mpq введите первый; т.е. mpfr(mpq('0.03125')),

Актуальной проблемой является режим округления по умолчанию. Промежуточная сумма находится точно посередине между двумя 4-битными значениями. Режим округления по умолчанию RoundToNearest выбирает округленное значение с последним битом 0. Если вы измените режим округления на RoundUp, вы получите ожидаемый результат.

>>> from gmpy2 import *
>>> ctx=context(emax=4, emin=-4, precision=4)
>>> set_context(ctx)
>>> a=mpfr('0.75')
>>> b=mpfr('0.03125')
>>> "{0:.10Df}".format(a+b)
'0.7500000000'
>>> get_context().round=RoundUp
>>> "{0:.10Df}".format(a+b)
'0.8125000000'

Последний комментарий: значения precision, emax а также emin немного отличаются между стандартами IEEE и библиотекой MPFR. Если e размер экспоненты и p это точность (в терминах IEEE), то precision должно быть p+1,emax должно быть 2**(e-1) а также emin должно быть 4-emax-precision, Это не влияет на ваш вопрос, так как это только меняет emax,

Другие вопросы по тегам