在存在任意编译器优化标志的情况下,如何计算给定类型名的机器舍入单元的“正确”值?如果不可能,让我们将可能的编译器标志集限制为由 -Ofast
设置的所有优化标志。
template<typename Tfloat>
Tfloat get_eps_mach(){
Tfloat x=1, q=0.5, u=q;
while( x!=(x+q*u) ){ u*=q; }
return u;
}
u
时,将为机器舍入单元
-Ofast
返回小得离谱的数字。我明白为什么(这是由于 -ffast-math
,它授予编译器操纵比较和增量的权限),但我寻求一种方法,以便我可以正确计算任意数字的 u
。注意:术语“正确”在这里的含义没有个人风格,因为值“u
”是根据数字类型的位表示(特别是尾数长度)正式定义的。
虽然在我的编程模型中,位表示应该是黑盒且无法实现的,并且我什至不想假设数字类型使用尾数或其他什么,但我仍然坚持持有一个不可知的函数,该函数将返回正确的值 u
。 (因此,建议为每个常见数字类型重载该函数也是一个毫无意义的“解决方案”。我感兴趣的原因是:
后续参数(例如,最佳截断、最佳扰动、合理公差等)将按照
u
的公式计算。get_eps_mach
函数都可能无法返回正确的值。