我想要一个floor
带语法的函数
int floor(double x);
但是std::floor
返回一个double
.是
static_cast(std::floor(x));
保证给我正确的整数,还是我有一个一个一个的问题?它似乎有效,但我想肯定地知道.
对于奖励积分,为什么heck确实在第一时间std::floor
返回double
?
double的范围大于32位或64位整数的范围,这就是为什么std::floor
返回a double
.铸造到int
应该罚款,只要它是在适当的范围内-但要知道,一个double
不能代表所有的64位整数准确,所以你也可以结束了错误,当你超越在其精度的点double
是这样的两个连续双打之间的差异大于1.
static_cast(std::floor(x));
做的几乎是你想要的,是的.它给出了最接近的整数,舍入为-infinity.至少只要您的输入在int表示的范围内.我不确定你是什么意思'添加.5和诸如此类的东西,但它不会产生同样的效果
并且std :: floor返回一个double,因为这是最常见的.有时您可能想要舍入浮点数或双倍,但保留类型.也就是说,从1.3f到1.0f,而不是1.
如果std :: floor返回一个int,那很难做到.(或者至少你有一个额外的不必要的演员在那里放慢速度).
如果floor只执行舍入本身而不更改类型,则可以在需要时将其强制转换为int.
另一个原因是双打范围远远大于整数范围.可能无法将所有双打四舍五入到整数.
C++标准说(4.9.1):
"浮点类型的右值可以被转换为整数类型的右值转换截断;即,小数部分被丢弃,则行为未定义如果截断值不能在目标类型来表示".
因此,如果要将double转换为int,则数字在int的范围内,并且所需的舍入为零,那么只需将数字转换为int就足够了:
(INT)X;
如果您想处理各种数字条件并希望以受控方式处理不同类型的转换,那么您可能应该查看Boost.NumericConversion.该库允许处理奇怪的情况(如超出范围,舍入,范围等)
以下是文档中的示例:
#include#include int main() { typedef boost::numeric::converter Double2Int ; int x = Double2Int::convert(2.0); assert ( x == 2 ); int y = Double2Int()(3.14); // As a function object. assert ( y == 3 ) ; // The default rounding is trunc. try { double m = boost::numeric::bounds ::highest(); int z = Double2Int::convert(m); // By default throws positive_overflow() } catch ( boost::numeric::positive_overflow const& ) { } return 0; }