std::nearbyint vs std::round in C++11
std::nearbyint vs std::round in C++11
C++11引入了std::nearint和std::round函数。两者都返回"最近"整数值。
我应该在何时何地选择其中一种?
我已经用0.5
的值测试了它们:
案例 1: 附近 int 的演示
#include <iostream>
#include <cmath>
int main()
{
std::cout<<"nearbyint(0.5) = "<<std::nearbyint(0.5);
}
输出:0
案例2:回合演示
#include <iostream>
#include <cmath>
int main()
{
std::cout<<"round(0.5) = "<<std::round(0.5);
}
输出:1
为什么输出不同?
std::round
函数忽略当前的舍入模式,而std::nearbyint
会将其考虑在内。您可以更改舍入模式:
#include <cfenv>
int main() {
std::fesetround(FE_UPWARD);
// perform calculations
std::fesetround(FE_DOWNWARD);
// perform calculations
// other rounding methods...
}
并观察不同的结果。要获取当前的舍入模式值,请使用 std::fegetround() 函数。默认值(已定义的实现)值可能0
转换为FE_TONEAREST
。
正如 Ron在回答中指出的那样,rint()
和nearbyint()
与round()
之间的一个区别是,后者使用固定舍入模式,而不管当前有效的动态舍入模式如何。在 2011 ISO C++ 标准中找不到这方面的细节,该标准在第26.8 C 库 [c.math]节中仅指向 C 标准。1999 ISO C 标准规定了round()
的操作如下:
7.12.9.6[...]round 函数将其参数舍入为浮点格式中最接近的整数值,将大小写四舍五入到一半 从零开始,无论当前舍入方向如何。
round()
使用的特定舍入模式在IEEE 754(2008)浮点标准的第4.3.1节中列为roundTiesToAway
,这意味着平局情况从零四舍五入。但是通常的绑定FE_TONEAREST
是IEEE-754(2008)舍入模式roundTiesToEven
,这意味着这样的平局情况四舍五入为偶数。实际上,这是我在我使用的众多系统平台上遇到的唯一FE_TONEAREST
实现,该支持fesetround()
。
在提问者的例子中,这两种舍入"到最近"变体的处理差异是显而易见的:当使用round()
时,0.5
舍入到下一个较大的(量级)整数(1
),但是当使用nearbyint()
或rint()
时,它会舍入到偶数(0
)。
- C++中的VLA,扩展名为std=C++11
- 编译器不会使用 -std=c++11 编译智能指针
- C ++枚举范围无法使用-std=c ++ 98进行编译,但使用-std=c ++ 11可以
- std::使用 -std=gnu++11 开关编译时相等错误
- "unix" C++预处理器宏未定义 -std=c++11
- 用STD = C 11或其他标准编译Boost,例如Ash C 14
- 网站组装 |错误:'C/ObjC'不允许使用无效'-std=c++11'参数
- G++ - 警告:扩展初始值设定项列表仅适用于 -std=C++11 或 -std=GNU++11
- 如何避免每次编译时都必须键入 -std=c++11
- 无法用"-std=c++11"编译《你好世界》
- 无法在Eclipse Neon.3中同时使用-std = C 11和-l/-l选项
- Cython -STD = C 11错误,使用C和C
- 扩展初始化器列表仅可用-STD = C 11或-STD = GNU 11中的C
- 为什么将语言标准从-STD = GNU 98到-STD = GNU 11
- 为什么 std::move 未定义,尽管编译器使用 -std=c++11 调用
- 我可以安全地将编译的库与-STD = C 11和-STD = C 14
- MATLAB MEX:-STD = C 11使用,但MEX错误仍然是错误
- Makefile with -std=c++11
- CUDA 8 编译错误与 -std=gnu++11
- QT 5.7将-STD = GNU 11添加到我的编译器标志,Clobbering -Std = C 14