Skip to content

整数除法的表达式取值

整数除法的取整方向

C99 起, 两个整数做 / 运算时, 结果是代数商去掉小数部分, 在数轴上朝 0 靠拢. 标准脚注里把这称为 truncation toward zero (向零截断).

表达式 代数商 / 的结果 Floor Ceiling
5 / 2 2.5 2 2 3
(-5) / 2 -2.5 -2 -3 -2
5 / (-2) -2.5 -2 -3 -2
(-5) / (-2) 2.5 2 2 3

规律可以概括为:

  • 商为正 (两操作数同号) → 向零截断与 Floor 一致

  • 商为负 (两操作数异号) → 向零截断与 Ceiling 一致

  • 能整除时, 三者相同

常见误解

整数除法既不是 Floor 也不是 Ceiling. 决定它与谁等价的是商的符号, 不是单个操作数的正负.

例如 (-5) / (-2) 的两个操作数都为负, 但商为正, 结果 2 仍是 Floor, 不是 Ceiling. 因此不能说「操作数为正时相当于 Floor, 为负时相当于 Ceiling」.

C89 中, 若有一方为负数, 取整方向是implementation-defined; 现代编译器普遍遵循 C99 的向零截断.

正整数情形

当 x 和 n 均为正整数时, 商恒为正, 向零截断恰好就是 Floor:

x / n    // Floor. 例: 17 / 4 == 4

Ceiling 则要求「有余数就进 1, 能整除则不变」, 不能单靠 / 完成. 常见写法有三种:

x / n + x % n              // 写法 1: 利用余数作进位标志
(x + n - 1) / n            // 写法 2: 先凑整再除
x / n + (x % n != 0)       // 写法 3: 显式判断
x n x/n (Floor) x/n + x%n (x+n-1)/n
17 4 4 4 + 1 = 5 20 / 4 = 5
16 4 4 4 + 0 = 4 19 / 4 = 4

当 x 不能被 n 整除时, 余数 x % n 落在 1 … n-1, 作为整数加到商上恰好等于 +1. 能整除时余数为 0, 不加 1.

这一写法仅适用于 x, n 均为正整数. 操作数可能为负时, 需要另写逻辑.

Example

例如, 假设变量x和n是两个正整数,我们知道x/n这个表达式的结果要取Floor,例如x是17,n是4,则结果是4。如果希望结果取Ceiling应该怎么写表达式呢?例如x是17,n是4,则结果是5;x是16,n是4,则结果是4。

就可以通过下面的程序解决:

#include <stdio.h>

int main(){
  int x = 17;
  int n = 4;
  printf("Floor of x/n: %d\nCeiling of x/n: %d\n", x/n, x/n + x%n);

  return 0;
}

运行输出:

Floor of x/n: 4
Ceiling of x/n: 5

若把x的值替换成16, 由于x%n的值为0, 因此就不会产生ceiling的值了:

Floor of x/n: 4
Ceiling of x/n: 4