【发布时间】:2018-11-12 14:50:07
【问题描述】:
我正在尝试编写constexpr 版本的exp 函数。我知道
- 我使用的算法是为
FE_TONEAREST舍入设计的 - 从C++11开始,可以通过
fesetround( int round )更改舍入模式(前提是支持#pragma STDC FENV_ACCESS并设置为ON) - 我不允许在我自己的
constexpr函数中调用非 constexpr 函数fesetround(int)
如果我的理解是正确的,这意味着(在支持#pragma STDC FENV_ACCESS 的编译器中),用户可以在调用我的函数之前设置舍入模式,但不允许我的函数取消此操作更改(即使是暂时的),因此可能会以错误的舍入模式执行。
我能想到的最佳选择是有两个功能:
- 版本 A 标记为
constexpr且未设置舍入模式 - 版本 B 没有标记为
constexpr并做了 3 件事:- 将舍入模式设置为
FE_TONEAREST - 调用版本 A
- 重置舍入模式
- 返回版本A的结果
- 将舍入模式设置为
要设置constexpr 变量,必须调用版本A,但它总是会被评估为好像舍入模式是FE_TONEAREST,因为(根据cppreference):
当前的舍入模式不影响 .... 结果 常量表达式中的浮点算术运算符(总是 最近的)
在非 constexpr contexts 中,只要舍入模式为 FE_TONEAREST,版本 A 和版本 B 会一致,但版本 B 将为任何其他舍入模式提供更好的结果。用户有责任使用FE_TONEAREST 舍入或确保调用版本 B。
在标准 C++ 中是否有更好的方法来处理这个问题? ...或者标准是否有其他关于舍入模式的内容,这使得整个问题变得毫无意义?
编辑:我的目标不是尊重舍入模式;是为了忽略它,以便函数的准确性是一致的。我宁愿只使用版本 B,但无法在 constexpr 函数中更改舍入模式。
【问题讨论】:
-
所以调用版本 A(如果不是
constexpr)的结果可能/应该根据舍入模式而有所不同? -
是的;该算法执行浮点加法/乘法,因此在非
constexpr上下文中,我希望它尊重舍入模式 -
所以您希望编译时间常数在运行时具有不同的值?它不能。您可以在运行时选择不同的
constexpr值,也可以在运行时计算(使用当前舍入模式)。 -
@user1476176:由于英语的性质,您所说的“我希望它尊重舍入模式”是模棱两可的。目前尚不清楚您的意思是您期望值会有所不同,因为舍入模式实际上会影响操作,或者您的意思是您希望结果取决于舍入模式.
-
@1201ProgramAlarm:见我上面的评论。
标签: c++ floating-point rounding