在C++ 11中std :: nearbyint vs std :: round

msc*_*msc 11 c++ floating-point rounding c++11

C++ 11引入了std :: nearbyintstd :: round函数.两者都返回"最接近的"整数值.

我应该何时何地更喜欢一个?

我用以下值测试了它们0.5:

案例1:附近的演示

#include <iostream>
#include <cmath>

int main()
{
    std::cout<<"nearbyint(0.5) = "<<std::nearbyint(0.5);
}
Run Code Online (Sandbox Code Playgroud)

输出: 0

案例2: 圆形演示

#include <iostream>
#include <cmath>

int main()
{
    std::cout<<"round(0.5) = "<<std::round(0.5);
}
Run Code Online (Sandbox Code Playgroud)

输出: 1

为什么输出不同?

Ron*_*Ron 20

std::round功能忽略了当前的舍入模式,同时std::nearbyint将其考虑在内.您可以更改舍入模式:

#include <cfenv>
int main() {
    std::fesetround(FE_UPWARD);
    // perform calculations
    std::fesetround(FE_DOWNWARD);
    // perform calculations
    // other rounding methods...
}
Run Code Online (Sandbox Code Playgroud)

并观察不同的结果.要获取当前舍入模式值,请使用std :: fegetround()函数.机会是默认(实现定义)值0转换为FE_TONEAREST.


nju*_*ffa 6

正如指出的Ron的答案,之间的一个差rint(),并nearbyint()一方面,以及round()在另一方面,在于后者采用的是固定的舍入模式,而不管的动态当前有效舍入模式。在 2011 ISO C++ 标准中找不到详细信息,该标准在第26.8C 库 [c.math] 中仅指向 C 标准。1999 ISO C 标准规定的操作round()如下:

7.12.9.6 [...] round 函数将其参数四舍五入到最接近的浮点格式整数值,将中间情况从零舍入,而不管当前的舍入方向如何。

使用的特定舍入模式在 IEEE 754 (2008) 浮点标准的round()4.3.1 节中列为roundTiesToAway,这意味着平局从零舍入。但是通常的 绑定FE_TONEAREST是 IEEE-754 (2008) 舍入模式roundTiesToEven,这意味着这种情况会舍入为偶数。事实上,这是我在使用该支持的众多系统平台中遇到的唯一实现。FE_TONEARESTfesetround()

在舍入的这两个变型的处理“以最近的”不同的是在提问者的例子显而易见:0.5四舍五入到下一个较大的(量值)整数(1使用时)round(),但它舍入为偶整数(0)时nearbyint()rint()使用.