6

我在代码库的实用程序标头中找到了以下宏:

#define CEILING(x,y) (((x) + (y) - 1) / (y))

其中(在此答案的帮助下)我已解析为:

// Return the smallest multiple N of y such that:
//   x <= y * N

但是,无论我多么盯着这个宏在我们的代码库中的使用方式,我都无法理解这种操作的价值。没有评论任何用法,这似乎表明它是显而易见的。

谁能提供这个宏的用例的英文解释?应该很明显吧,我就是看不出来。。。

4

5 回答 5

5

假设您想以块的形式分配内存(想想:缓存行、磁盘扇区);X保存包含字节的整数块需要多少内存?如果夹头尺寸为Y,则答案为:CEILING(X,Y)

于 2012-07-06T13:47:16.300 回答
5

当您像这样在 C 中使用整数除法时

y = a / b

你会得到一个四舍五入到零的除法结果,即5 / 2 == 2, -5 / 2 == -2。有时希望以另一种方式对其进行舍入5 / 2 == 3,例如,如果您想采用最小的整数数组大小来保存n字节,则需要进行n / sizeof(int)四舍五入,因为您需要空间来保存额外的字节。

所以这个宏正是这样做的:CEILING(5,2) == 3,但请注意它只适用于正数y,所以要小心。

于 2012-07-06T13:47:34.927 回答
4

嗯...英语示例...您只能以 5 根为一组购买香蕉。您有 47 个人想要一根香蕉。你需要多少束?答案 = CEILING(47,5) = ((47 + 5) - 1) / 5 = 51 / 5 = 10 (去掉余数 - 整数除法)。

于 2012-07-06T13:56:43.467 回答
3

让我们尝试一些测试值

CEILING(6, 3) = (6 + 3 -1) / 3 = 8 / 3 = 2 // integer division
CEILING(7, 3) = (7 + 3 -1) / 3 = 9 / 3 = 3
CEILING(8, 3) = (8 + 3 -1) / 3 = 10 / 3 = 3
CEILING(9, 3) = (9 + 3 -1) / 3 = 11 / 3 = 3
CEILING(10, 3) = (9 + 3 -1) / 3 = 12 / 3 = 4

如您所见,宏的结果是一个整数,z它是满足以下条件的最小可能:z * y >= x.

我们也可以尝试使用符号:

CEILING(k*y, y) = (k*y + y -1) / y = ((k+1)*y - 1) / y = k
CEILING(k*y + 1, y) = ((k*y + 1) + y -1) / y = ((k+1)*y) / y = k + 1
CEILING(k*y + 2, y) = ((k*y + 2) + y -1) / y = ((k+1)*y + 1) / y = k + 1
....
CEILING(k*y + y - 1, y) = ((k*y + y - 1) + y -1) / y = ((k+1)*y + y - 2) / y = k + 1
CEILING(k*y + y, y) = ((k*y + y) + y -1) / y = ((k+1)*y + y - 1) / y = k + 1
CEILING(k*y + y + 1, y) = ((k*y + y + 1) + y -1) / y = ((k+2)*y) / y = k + 2

您可以使用它来分配具有常量倍数大小的内存,以确定填充屏幕需要多少块瓷砖等。

不过要小心。这仅适用于正面y

希望能帮助到你。

于 2012-07-06T13:49:15.333 回答
2

CEILING(x,y)假设 给你(数学除法)y > 0的上限。x/y一个用例是从 offset 开始的素数筛子x,您可以将y筛子范围内的所有素数倍数标记为复合物。

于 2012-07-06T13:47:29.250 回答