1

一个简单的浮点加法 x+y in 精度为 4(即 IEEE 尾数宽度 3),其中 3 位用于 的指数(emax=3, emin=-4x = 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)
>>>
4

1 回答 1

4

免责声明:我维护 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'

最后一条评论: 和 的值在 IEEE 标准和MPFRprecision库之间略有不同。如果是指数大小并且是精度(在 IEEE 术语中),那么应该是、应该是并且应该是。这不会影响您的问题,因为它只会更改。emaxeminepprecisionp+1emax2**(e-1)emin4-emax-precisionemax

于 2016-01-19T16:22:39.053 回答