50

我想要一个floor具有语法的函数

int floor(double x);

std::floor返回一个double. 是

static_cast <int> (std::floor(x));

保证给我正确的整数,还是我有一个不合一的问题?它似乎有效,但我想确定。

对于奖励积分,为什么首先std::floor返回 adouble呢?

4

5 回答 5

32

double 的范围远大于 32 或 64 位整数的范围,这就是std::floor返回 a 的原因doubleint只要它在适当的范围内,转换为就应该没问题 - 但请注意,adouble不能准确地表示所有 64 位整数,因此当您超出精确度的点时,您也可能会出现double错误连续两次双打之差大于1。

于 2009-03-03T08:26:42.027 回答
18
static_cast <int> (std::floor(x));

几乎可以满足您的需求,是的。它为您提供最接近的整数,向 -infinity 四舍五入。至少只要您的输入在整数可表示的范围内。我不确定'添加 .5 之类的东西是什么意思,但它不会产生相同的效果

std::floor 返回一个双精度值,因为这是最通用的。有时您可能希望对浮点数或双精度数进行四舍五入,但保留类型。也就是说,将 1.3f 舍入到 1.0f,而不是 1。

如果 std::floor 返回一个 int,那将很难做到。(或者至少你会有额外的不必要的演员在那里减慢速度)。

如果 floor 仅执行舍入本身,而不更改类型,则可以在需要时将其转换为 int 。

另一个原因是双精度数的范围远大于整数。可能无法将所有双精度数舍入为整数。

于 2009-03-03T08:27:07.173 回答
8

C++ 标准说(4.9.1):

“浮点类型的右值可以转换为整数类型的右值。转换截断;也就是说,小数部分被丢弃。如果截断的值不能在目标类型中表示,则行为未定义”。

因此,如果要将 double 转换为 int,则该数字在 int 范围内,并且所需的向上舍入为零,那么只需将数字转换为 int 就足够了:

(int)x;

于 2009-05-26T12:37:49.820 回答
5

如果您想处理各种数字条件并希望以受控方式处理不同类型的转换,那么也许您应该查看Boost.NumericConversion。这个库允许处理奇怪的情况(如超出范围、舍入、范围等)

这是文档中的示例:

#include <cassert>
#include <boost/numeric/conversion/converter.hpp>

int main() {

    typedef boost::numeric::converter<int,double> 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<double>::highest();
        int z = Double2Int::convert(m); // By default throws positive_overflow()
    }
    catch ( boost::numeric::positive_overflow const& )
    {
    }

    return 0;
}
于 2009-03-03T08:33:48.200 回答
2

大多数标准数学库使用双精度,但也提供浮点版本。如果您不想使用双精度数,则 std::floorf() 是 std::floor() 的单精度版本。

编辑:我已经删除了我之前答案的一部分。我曾说过在转换为 int 时地板是多余的,但我忘记了这仅适用于正浮点数。

于 2009-03-03T08:37:53.090 回答