我想知道C ++是否包含了一种舍入到最接近的偶数的方法。我环顾四周,似乎无法找到关于这个主题的任何内容。我可以编写自己的方法,但使用内置方法很可能会更快。
感谢。
答案 0 :(得分:6)
没有内置功能来执行此操作。最直接的方法可能是做一些事情:
even = round(x / 2) * 2;
答案 1 :(得分:3)
如前所述,没有内置方式。因此,让我们看看可以采取的一些方法。但首先......
表现警告:
std::round( x * 0.5f ) * 2.0f
这将在每个奇数处偏离零,产生一个小的偏差。
一般情况下,如果可能,请避免使用std::round
。由于它必须:保存舍入模式,切换,舍入,然后恢复先前的舍入模式,因此它很慢。这一切都可以引入偏见。
Pre C ++ 11,我们可以使用魔术数字来减轻使用内置银行家舍入的偏见。 警告:这取决于舍入模式是默认值(FE_TONEAREST
),它通常是99.9999%的时间,但要警惕其他库可能会更改它而不是之后恢复它
float
魔术:( x + 25165824f ) - 25165824f
这使用了浮点精度仅为这么多位的事实。通过添加足够大的幻数,我们不想要的最低位将自动舍入,之后我们减去我们的幻数,使我们的原始舍入到正确的精度。
幻数计算为1.5 * 2 p 其中 p 是浮点有效数的精度:{{1 } {,float
为53,double
为64。在long double
的帮助下,我们可以将其设为通用。
std::numeric_limits
通过更改 p 作为我们的幻数,我们可以舍入到两个不同的幂。 p - 1会创建标准银行家的四舍五入。
所有人都欢呼新的回合方式:std::nearbyint
。这符合当前的舍入模式,因此如果舍入模式被其他内容模式化,我们可以使用std::fesetround
将其还原为template< typename T >
T magic_round_to_even( T x ) {
static T magic = 1.5 * std::pow( 2.0L, std::numeric_limits< T >::digits);
return ( x + magic ) - magic;
}
。
FE_TONEAREST
这与第一个版本一样直观,但没有任何偏见。