贝利信息

c++ ceil和floor函数_c++向上取整与向下取整

日期:2026-01-03 00:00 / 作者:裘德小鎮的故事
ceil 和 floor 函数需包含 ,参数隐式转 double,整数除法如 ceil(10/3) 错误因先整除得 3;安全整数向上取整用 (a + b - 1) / b(正数)或 std::ceil(static_cast(a)/b)。

ceil 和 floor 函数必须包含 ,且参数为 double 或可隐式转为 double 的类型

直接调用 ceil(3)floor(5) 看似没问题,但实际是调用 double ceil(double) 的重载版本。C++ 标准库中没有 int 版本的 ceil/floor,传入整数会触发隐式转换,看似能编译,但容易掩盖精度问题或误用场景。

常见错误现象:ceil(10 / 3) 返回 3.0(不是 4.0),因为 10 / 3 是整数除法,结果为 3,再转 double 后取整仍是 3.0

向上取整常见写法:避免依赖 ceil 处理整数除法

对两个正整数 ab 求「向上取整的商」(即 ⌈a/b⌉),用 ceil(static_cast(a)/b) 简单但有隐患:当 ab 很大时,double 可能无法精确表示,导致取整错误(例如 a = 2^53 + 1double 中与 2^53 无法区分)。

更安全、无精度损失的整数解法:

立即学习“C++免费学习笔记(深入)”;

int ceil_div(int a, int b) {
    if (b == 0) return 0; // 或抛异常
    if (a == 0) return 0;
    if ((a > 0) == (b > 0)) {
        // 同号:(a + b - 1) / b,但要防溢出
        return (a + (b - 1)) / b;
    } else {
        // 异号:C++11 起整数除法向零取整,直接用负数处理更稳妥
        return a / b - (a % b != 0 ? (a > 0 ? 1 : 0) : 0); // 建议改用标准库 std::div 或分情况
    }
}

实际项目中更推荐用:

floor 在负数除法中的行为易被误解

C++ 整数除法向零取整(-7 / 3 == -2),而 floor(-7.0 / 3.0)-3.0 —— 二者结果不同。这是最常踩的坑:误以为 floor(a / b) 和整数除法等价。

示例对比:

int a = -7, b = 3;
std::cout << a / b << "\n";           // 输出 -2(向零)
std::cout << floor(a * 1.0 / b) << "\n"; // 输出 -3(向下)
std::cout << ceil(a * 1.0 / b) << "\n";  // 输出 -2(向上)

编译器与 IEEE 754 兼容性影响结果一致性

虽然 中的 ceil/floor 行为由 IEEE 754 定义,但某些嵌入式平台或老编译器(如早期 MSVC)可能未完全遵循,尤其在 long double 模式下。

实操建议:

真正麻烦的不是函数怎么写,而是你没意识到它背后连着整个浮点环境和整数溢出链。