我在代码库的一个实用程序头中发现了以下宏:
#define CEILING(x,y) (((x) + (y) - 1) / (y))
在this answer的帮助下,我将其解析为:
// Return the smallest multiple N of y such that:
// x <= y * N
但是,无论我如何盯着这个宏在我们的代码库中是如何使用的,我都无法理解这样一个操作的价值。没有任何用法被注解,这似乎表明它是显而易见的。
谁能用英语解释一下这个宏的用例?很明显,我就是看不出来...
6条答案
按热度按时间hof1towb1#
假设你想分块分配内存(想想:高速缓存行、磁盘扇区);需要多少内存才能容纳整数个包含
X
字节的块?如果卡盘尺寸为Y
,则答案为:CEILING(X,Y)
ukxgm1gy2#
当你像这样在C中使用整数除法时
你会得到一个四舍五入的除法结果,即
5 / 2 == 2
,-5 / 2 == -2
。有时候需要用另一种方式舍入它,例如,如果你想用最小的整数数组大小来容纳n
字节,你会希望n / sizeof(int)
向上舍入,因为你想用空间来容纳额外的字节。这个宏就是这样做的:
CEILING(5,2) == 3
,但请注意,它只适用于正y
,所以要小心。mcvgt66p3#
嗯……英语例子……你只能买五根一捆的香蕉。有47个人想要香蕉。你需要多少束?答案= CEILING(47,5)=((47 + 5)- 1)/ 5 = 51 / 5 = 10(去掉余数-整数除法)。
lymnna714#
让我们尝试一些测试值
正如你所看到的,宏的结果是一个整数,最小的可能
z
满足:z * y >= x
。我们也可以尝试使用符号:
你可以用它来分配一个常数倍数大小的内存,来决定需要多少块来填满一个屏幕,等等。
不过要小心这只适用于正的
y
。希望能帮上忙。
vfhzx4xs5#
假设
y > 0
,CEILING(x,y)
给出了x/y
的上限(数学除法)。其中一个用例是从偏移量x
开始的素数筛,您可以将筛范围中素数y
的所有倍数标记为复合。guicsvcw6#
我知道这个问题很久以前了,但我找到了为什么你会使用这样的宏的原因,在C++中你有定义ceil(double x)的std,但它实际上有一个缺陷:当你试图在里面执行除法时,你会得到一个四舍五入的参数。考虑一下这个codeforces问题:B. Long Legs。它是使用以下公式的蛮力求解的:
现在如果你使用stdceil,你会得到完全错误的值,因为参数中的类型转换;
输出(错误)
现在使用正确的宏
输出(正确)
如果你仍然想使用std::ceil,你可以这样做:
std::ceil((double)a/i) + std::ceil((double)b/i) + i-1;