【发布时间】:2009-08-25 07:11:49
【问题描述】:
您好,我想在 C++ 中像这样(远离零)舍入双数:
4.2 ----> 5
5.7 ----> 6
-7.8 ----> -8
-34.2 ----> -35
这样做的有效方法是什么?
【问题讨论】:
-
从(原始)标题“C++ 双舍入”,我以为你的意思是把一个数字舍入两次,只是为了确定 :-)
您好,我想在 C++ 中像这样(远离零)舍入双数:
4.2 ----> 5
5.7 ----> 6
-7.8 ----> -8
-34.2 ----> -35
这样做的有效方法是什么?
【问题讨论】:
inline double myround(double x)
{
return x < 0 ? floor(x) : ceil(x);
}
正如the article Huppie cites 中所述,最好将其表示为适用于所有浮点类型的模板
见http://en.cppreference.com/w/cpp/numeric/math/floor和http://en.cppreference.com/w/cpp/numeric/math/floor
或者,感谢 Pax,一个非功能版本:
x = (x < 0) ? floor(x) : ceil(x);
【讨论】:
CPlusPlus.com 上有一篇关于类似问题的好文章。您的问题的简单解决方案应该是这样的:
double customRound( double value ) const {
return value < 0 ? floor( value ) : ceil( value );
}
一个更好的解决方案是文章中提到的,它使用了一个模板:
//--------------------------------------------------------------------------
// symmetric round up
// Bias: away from zero
template <typename FloatType>
FloatType ceil0( const FloatType& value )
{
FloatType result = std::ceil( std::fabs( value ) );
return (value < 0.0) ? -result : result;
}
【讨论】:
template <typename floattype> FloatType ceil0( const FloatType& value ) { FloatType result = std::ceil( std::fabs( value ) );返回(值 有趣的文章,+1</typename>
return (value < 0.0) ? -std::ceil(-value) : std::ceil(value)
Ruben Bartelink 的 x < 0 ? floor(x) : ceil(x); 方法很好。但是考虑一下x = -0.0、x = NaN 的特殊情况会发生什么。
与其让myround(-0.0) 可能返回+0.01 并让myround(NaN) 返回带有NaN 的更改有效负载,请考虑以下内容。
myround_alt(-0.0) 返回-0.0。
myround_alt(NaN)更有可能返回不变的有效载荷 NaN。非数字的东西很棘手,也没有很好的定义。 IAC,是myround_alt(-0.0) --> -0.0 我要找的。p>
inline double myround_alt(double x) {
if (x > 0) return ceil(x);
if (x < 0) return floor(x);
return x;
}
1IEC 60559 floating-point arithmetic 指定ceil(±0) 返回±0,因此严格遵循该规范的实现不需要这种方法。然而,许多 C 浮点实现不遵循这一点(C 不需要它)或在这种情况下失败。
【讨论】:
试试
double rounded = _copysign(ceil(abs(x)), x);
【讨论】:
abs 将符号位与 0 进行位与运算,执行 ceil(祈祷快点完成),然后重新签名通过将其符号位与原始符号位进行位或运算得到结果。 无条件 = 无分支错误预测 = 无管道刷新 = 非常快。