对一个数或者表达式实现向上整除

导语

“向上取整”是编程中最常用的小操作之一,但 C 标准库并没有给整数版本开箱即用的接口。本文总结几种零依赖、可嵌入的写法,并指出浮点场景的正确打开方式。

一、需求场景

  • 分页计算:总记录数 n,每页 m 条,需要多少页?
  • 内存对齐:申请 n 字节,按 m 字节对齐,至少分配多少?
  • 任务打包:n 个任务,每批处理 m 个,需要多少批?

以上问题本质都是「n ÷ m 向上取整」。

二、整数向上取整:一句代码就够

int ceildiv(int n, int m)
{
    return (n + m - 1) / m;   /* m > 0 时成立 */
}

原理:先把余数“补满”到 m-1,再整除 m,相当于进一位。

复杂度:O(1),无分支,不调用任何库。

三、宏版:编译期内联

#define CEILDIV(n, m) (((n) + (m) - 1) / (m))

注意:m 为负数时需先取绝对值或另行处理。

四、浮点场景:用标准库 ceil

#include <math.h>

double x = 10.0 / 3.0;
double y = ceil(x);   /* y == 4.0 */

返回类型仍是浮点,如需整数再强转:(int)ceil(x)

五、完整示例

#include <stdio.h>
#include <math.h>

#define CEILDIV(n, m) (((n) + (m) - 1) / (m))

int main(void)
{
    int n = 10, m = 3;
    printf("integer ceildiv: %d\n", CEILDIV(n, m));  /* 4 */

    double x = (double)n / m;
    printf("float ceil: %.0f\n", ceil(x));           /* 4 */
    return 0;
}

六、常见疑问

  1. 为什么标准库没有整数 ceil?
    历史原因:早期 C 主要面向系统/底层,整数除法已够用,且「(a+b-1)/b」足够简单。
  2. 会溢出吗?
    m > 0a + m - 1 不超过对应类型最大值时安全;若担心,可用更大宽度类型或判断分支。
  3. 负数怎么办?
    若 m 为负,先取绝对值;若 a 为负,需先定义“向上”语义(向零还是向负无穷)。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇