找回密码
 register

QQ登录

只需一步,快速开始

查看: 13|回复: 0

[C++] std::floor函数 向下取整 详细用法特性

[复制链接]

[C++] std::floor函数 向下取整 详细用法特性

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:153
  • 打卡月天数:2
  • 打卡总奖励:152
  • 最近打卡:2025-04-03 08:28:12
Waylee

主题

0

回帖

1万

积分

仙帝

积分
18932
Waylee 2025-4-3 09:45 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

关联相关文章:std::ceil函数 向下取整 详细用法特性 本文也是对ceil的扩展

功能:返回不大于给定数值的最大整数(向下取整)。

特点:

  • 对于正数,它的效果就是取整数部分。例如,std::floor(3.7) 返回 3.0。

  • 对于负数,由于向下取整意味着“更小”的整数,所以 std::floor(-3.7) 返回 -4.0。

返回类型:返回与参数相同类型的浮点数(通常为 double、float 或 long double)。

示例代码

#include <iostream>
#include <cmath>
int main() {
    double a = 3.7;
    double b = -3.7;

    std::cout << "std::floor(" << a << ") = " << std::floor(a) << std::endl; // 输出 3.0
    std::cout << "std::floor(" << b << ") = " << std::floor(b) << std::endl; // 输出 -4.0

    return 0;
}

使用注意事项

整数情况:如果传入的数值本身就是整数(如 5.0),std::floor(5.0) 和 std::ceil(5.0) 都将返回 5.0。

负数处理:由于负数的向下取整和向上取整效果与正数不同,务必注意结果。例如,std::floor(-2.1) 得到 -3.0,而 std::ceil(-2.1) 得到 -2.0。

返回类型:虽然结果看起来像整数,但返回类型依然是浮点类型,因此在比较或赋值时可能需要注意类型转换问题。

陷阱案例

浮点数精度问题

边界误差:由于浮点数表示的精度有限,如果一个数非常接近整数边界,可能会因舍入误差导致预期之外的结果。

#include <iostream>
#include <cmath>
int main() {
    double a = 2.999999999999999;
    // 理论上接近 3,但由于浮点精度问题,可能会返回 2.0(floor)
    std::cout << "std::floor(a) = " << std::floor(a) << std::endl;
    return 0;
}

说明:在处理接近整数的数值时,建议引入适当的容差进行比较。

负数和截断的混淆

与截断函数的区别:

  • std::floor 是向下取整(结果可能比原数更小),而 std::trunc 则是简单地截取整数部分(对负数不完全相同)。

示例:

#include <iostream>
#include <cmath>

int main() {
    double x = -2.3;
    std::cout << "std::floor(x) = " << std::floor(x) << std::endl; // 输出 -3.0
    std::cout << "std::trunc(x) = " << std::trunc(x) << std::endl; // 输出 -2.0
    return 0;
}

说明:使用时需明确选择正确的函数,避免将截断误认为取整。

负零(-0.0)的特殊情况

负零的存在:IEEE 浮点标准中存在 -0.0 和 0.0 的区分。
std::floor(-0.0) 通常会返回 -0.0,而 std::ceil(-0.0) 也会返回 -0.0。
注意:在某些情况下,这种微妙的差异可能会影响后续的比较或逻辑判断。

非有限数值(NaN 与无穷大)的处理

NaN 和无穷大:

  • 当输入为 NaN 时,std::floor 和 std::ceil 通常会返回 NaN。
  • 对于正无穷和负无穷,结果依然是正无穷和负无穷。
#include <iostream>
#include <cmath>
int main() {
    double nanVal = std::nan("");
    double posInf = std::numeric_limits<double>::infinity();
    double negInf = -std::numeric_limits<double>::infinity();

    std::cout << "std::floor(NaN) = " << std::floor(nanVal) << std::endl;
    std::cout << "std::ceil(NaN) = " << std::ceil(nanVal) << std::endl;
    std::cout << "std::floor(+inf) = " << std::floor(posInf) << std::endl;
    std::cout << "std::ceil(-inf) = " << std::ceil(negInf) << std::endl;
    return 0;
}

说明:编写健壮的代码时,应对这些特殊数值进行额外判断。

类型转换问题

隐式转换:

  • 当传入整数或其他类型时,会隐式转换为浮点型,结果依然为浮点数。
  • 若需要整数结果,需手动转换(注意可能会截断精度)。

示例:

#include <iostream>
#include <cmath>
int main() {
    int x = 5;
    // 计算后依然是 double 类型
    double result = std::floor(x);
    // 若需要整数,需进行显式转换
    int intResult = static_cast<int>(result);
    std::cout << "转换后的整数为 " << intResult << std::endl;
    return 0;
}

总结

  • 在使用 std::floor 和 std::ceil 时,除了基本用法外,还需要关注:

  • 浮点数精度和舍入误差可能导致边界值计算结果异常。

  • 负数取整行为与截断函数存在区别。

  • 特殊数值(如 -0.0、NaN、无穷大)的处理要特别小心。

  • 隐式类型转换可能导致意想不到的结果,必要时应进行显式转换。

  • 编译期计算(constexpr)依赖编译器和库的支持情况。

通过注意这些细节,可以避免在实际开发中遇到不必要的错误或陷阱。

您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-4-4 06:40 , Processed in 0.294401 second(s), 6 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表