问题:给定一个浮点常量表达式,我们可以编写一个宏来计算一个常量表达式,该常量表达式的值是等于尾数最高位的 2 的幂吗?等效地,这只是小于或等于输入幅度的两个的最大幂。
出于这个问题的目的,我们可以忽略:
- 接近溢出或接近下溢值(它们可以通过有限多次应用来处理)
?:
重新缩放)。
- 负输入(可以同样处理)。
- 不符合附件 F 的实现(实际上不能用它们在浮点中做任何有用的事情)。
- 围绕过度精度的怪异(
float_t
and double_t
可以与FLT_EVAL_METHOD
和别的float.h
宏来安全地处理它)。
因此,解决远离无穷大和非正规范围的正值问题就足够了。
请注意,此问题相当于查找特定值的“epsilon”,即nextafter(x,INF)-x
(或等效于float
or long double
),结果只是按比例缩放DBL_EPSILON
(或该类型的等效项)。如果解决方案更简单,那么它们是完全可以接受的。
我有一个建议的解决方案作为自我回答发布,但我不确定它是否正确。
If您可以假设 IEEE 754 二进制 64 格式和语义(特别是算术运算正确舍入),以及舍入到偶数舍入模式,那么这是一个很好的事实,对于任何不太小的不太-大正有限double
value x
,下一个可表示的值x
总是由x / 0x1.fffffffffffffp-1
(where 0x1.fffffffffffffp-1
只是1.0 - 0.5 * DBL_EPSILON
拼写为十六进制文字)。
因此,我们可以简单地从以下位置获得您要求的最重要的部分:
(x / 0x1.fffffffffffffp-1 - x) * 0x1.0p+52
当然也有类似的结果float
,假设 IEEE 754 binary32 格式和语义。
事实上,唯一失败的正常正值是DBL_MAX
,其中除法的结果溢出到无穷大。
要证明除法技巧有效,只需证明它即可x
在范围中1.0 <= x < 2.0
;很容易证明对于任何x
在此范围内,值x / 0x1.fffffffffffffp-1 - x
(where /
在这种情况下表示数学除法)位于半开区间(2^-53, 2^52]
,因此在舍入到偶数(或实际上任何舍入到最近的舍入模式)下,x / 0x1.fffffffffffffp-1
向上舍入到下一个可表示的值。
同样,在同样的假设下,x * 0x1.fffffffffffffp-1
始终是下一个可表示的值x
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)