在C ++中舍入到最近偶数

时间:2015-07-16 20:42:16

标签: int rounding

我想知道C ++是否包含了一种舍入到最接近的偶数的方法。我环顾四周,似乎无法找到关于这个主题的任何内容。我可以编写自己的方法,但使用内置方法很可能会更快。

感谢。

2 个答案:

答案 0 :(得分:6)

没有内置功能来执行此操作。最直接的方法可能是做一些事情:

even = round(x / 2) * 2;

答案 1 :(得分:3)

如前所述,没有内置方式。因此,让我们看看可以采取的一些方法。但首先......

表现警告:

  • 避免分裂,因为它对于浮点数来说仍然很慢,尽管没有整数那么糟糕。乘法几乎与浮点数的加法一样快。
  • 对于任何整数x乘以2 -x 保证等效于 除以2 x ,但不会失去精确度。
  • 使所有常量都相同,以防止升级,尤其是当值再次存储在同一类型中时。

简单

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会创建标准银行家的四舍五入。

C ++ 11

所有人都欢呼新的回合方式: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

这与第一个版本一样直观,但没有任何偏见。