如何使用32位整数计算(2 ^ 32)/ n

时间:2018-03-05 00:33:51

标签: algorithm math 32-bit

我有一个32位定时器,我希望在n步之后溢出。这意味着每个步骤应为(2 ^ 32)/ n。但是,如果我尝试使用32位整数计算此数字,则编译器会抱怨(1 <&lt; 32)大于我正在使用的类型。

我可以非常接近我正在寻找的答案,而不是像(~0)/ n那样。然而,在这种情况下,当n为2的幂时,我不会得到正确的答案,这意味着在这些情况下,定时器溢出需要一个额外的步骤。

是否有一个简单的表达式只使用32位整数来计算(2 ^ 32)/ n?

2 个答案:

答案 0 :(得分:4)

如果您希望计数器在第n步(当可能的话)时溢出,那么您需要计算ceil(232 / n)。考虑两种可能的情况:

  1. n不是2的幂。在这种情况下,n不是232的因子,并且除法的上限恰好是地板的一个。此外,(使用截断整数除法,如在C或Java中)floor(232 / n) == floor((232 - 1) / n)。所以步骤是(232 - 1)/n + 1

  2. n是2的幂。在这种情况下,n精确地划分232,因此(232 - 1) / n将比232 / n小一。所以步骤是(232 - 1)/n + 1。方便的是,这与第一种情况下的值相同。

  3. 注意:正如@greybeard在评论中指出的那样,如果n > 216,则无法保证存在适当的步长。对于较大的n,上述过程将计算最大步长,以确保在步骤n之前不会发生溢出。

答案 1 :(得分:1)

如果您使用C作为编程语言,则可以使用其无符号算术。请考虑以下事项:

floor(232 / n) = floor((232 - n) / n + 1)

如果您的n具有无符号类型(例如uint32_t),则数学表达式232 - n可以简单地计算为-n

所以在C:

uint32_t n = ...;
uint32_t d = (-n) / n + 1;

可替换地:

uint32_t d = (0 - n) / n + 1;

你应该记录好,因为这是非常模糊的代码。