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

时间:2017-11-07 11:29:48

标签: c++ c++11 floating-point rounding

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

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

我使用0.5

的值测试了它们

案例1 Demo for nearbyint

#include <iostream>
#include <cmath>

int main()
{
    std::cout<<"nearbyint(0.5) = "<<std::nearbyint(0.5);
}

输出 0

案例2: Demo for round

#include <iostream>
#include <cmath>

int main()
{
    std::cout<<"round(0.5) = "<<std::round(0.5);
}

输出 1

为什么输出不同?

2 个答案:

答案 0 :(得分:16)

std::roundstd::nearbyint考虑在内时,#include <cfenv> int main() { std::fesetround(FE_UPWARD); // perform calculations std::fesetround(FE_DOWNWARD); // perform calculations // other rounding methods... } 功能会忽略current rounding mode。您可以更改舍入模式:

0

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

答案 1 :(得分:4)

正如Ron's answer所指出的,一方面rint()nearbyint()之间的差异,另一方面round()之间的区别在于后者使用固定舍入模式,无论当前有效的动态舍入模式如何。有关详细信息,请参见2011 ISO C ++标准,该标准在 26.8 C库[c.math] 一节中仅指向C标准。 1999 ISO C标准规定round()的操作如下:

  

7.12.9.6 [...]圆函数将它们的参数四舍五入为浮点格式的最接近的整数值,舍入中途的情况   从零开始,无论当前的舍入方向如何。

round()使用的特定舍入模式在IEEE 754(2008)浮点标准的 4.3.1 部分中列为roundTiesToAway,这意味着绑定案例是四舍五入。但是FE_TONEAREST的通常绑定是IEEE-754(2008)舍入模式roundTiesToEven,这意味着这种关系情况四舍五入为偶数。事实上,这是FE_TONEAREST的{​​strong>唯一实现,我曾在我使用该支持fesetround()的众多系统平台中遇到过。

处理这两种舍入方式的差异&#34;到最近的&#34;在提问者的例子中很明显:0.5在使用1时向下一个更大的(在数量上)整数(round())舍入,但它舍入为偶数(0 {1}})使用nearbyint()rint()时。