一个简单的浮点加法x + y in,精度为4(即IEEE尾数宽度为3),其中3位为emax=3
的指数(emin=-4
,x = mpfr('0.75')
),{ {1}}错误地将y = mpfr('0.03125')
作为结果mpfr('0.75')
。请注意,mpfr('0.8125')
是此精简格式缩减的次正规数。
编辑:从链接中提取的终端互动,并包含在内以供将来参考。
0.3125
答案 0 :(得分:4)
免责声明:我维持gmpy2。
我认为从字符串创建次正规是一个错误。我认为它已经在开发代码中得到了修复,但是直到后来我都无法测试。我稍后会更新此答案。
更新
问题与从字符串创建子正规无关。在这种情况下,正确创建子正常值。在gmpy2 2.0.x中,将字符串转换为subnormal时有一个罕见的错误。最简单的解决方法是首先将输入转换为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
。