c++ - 将 `std::floor()` 和 `std::ceil()` 转换为整数类型是否总是给出正确的结果?

标签 c++ math floating-accuracy arithmetic-expressions

我很怀疑这些函数之一可能会给出这样的错误结果:

std::floor(2000.0 / 1000.0) --> std::floor(1.999999999999) --> 1
or
std::ceil(18 / 3) --> std::ceil(6.000000000001) --> 7

这样的事情会发生吗?如果确实存在这样的风险,我打算使用下面的功能来安全地工作。但是,这真的有必要吗?

constexpr long double EPSILON = 1e-10;

intmax_t GuaranteedFloor(const long double & Number)
{
    if (Number > 0)
    {
        return static_cast<intmax_t>(std::floor(Number) + EPSILON);
    }
    else
    {
        return static_cast<intmax_t>(std::floor(Number) - EPSILON);
    }
}

intmax_t GuaranteedCeil(const long double & Number)
{
    if (Number > 0)
    {
        return static_cast<intmax_t>(std::ceil(Number) + EPSILON);
    }
    else
    {
        return static_cast<intmax_t>(std::ceil(Number) - EPSILON);
    }
}

(注意:我假设给定的“long double”参数将适合“intmax_t”返回类型。)

最佳答案

人们通常认为浮点运算产生的结果带有小的、不可预测的、准随机错误。此印象不正确。

浮点算术计算尽可能精确18/3 将始终产生 正好 61/3 的结果不会正好是三分之一,但它会是最接近三分之一的可表示为 float 的数字

因此,您展示的示例保证始终有效。至于您建议的“保证地板/天花板”,这不是一个好主意。某些操作序列很容易将错误排除在 1e-10 之上,而某些其他用例将要求 1e-10 被正确识别(和上限)为非零。

根据经验,硬编码的 epsilon 值是代码中的错误。

关于c++ - 将 `std::floor()` 和 `std::ceil()` 转换为整数类型是否总是给出正确的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34996987/

相关文章:

c++ - Qt 音乐流媒体

java - 在字符串中每一个或两个字符后插入空格

c++ - 反卷积 C++

c# - 计算 X 位掩码的最快方法?

c++ - 为什么编译时浮点计算的结果可能与运行时计算的结果不同?

c++ - 为什么这些基于范围的 for 循环不能正常工作?

c++ - C:声明后初始化结构变量

c++ - 为什么当我尝试重写指向 Direct3D 设备的 `EndScene` 函数的指针时什么也没有发生?

C语言 : scanf function producing different results with float and double types?

以特定精度将小值与零进行比较