我有一个32位的计时器,希望经过n个步骤后它会溢出。这意味着每一步应该是(2^32)/n。然而,如果我尝试使用32位整数计算这个数字,编译器会抱怨(1<<32)比我正在使用的类型更大。
我可以通过做像(~0)/n这样的事情来接近我要寻找的答案。然而,当n是2的幂时,这种情况会让我感到不安,因为在这些情况下,计时器需要多走一步才能溢出。
是否有一个简单的表达式,只使用32位整数就能计算出(2^32)/n?
我有一个32位的计时器,希望经过n个步骤后它会溢出。这意味着每一步应该是(2^32)/n。然而,如果我尝试使用32位整数计算这个数字,编译器会抱怨(1<<32)比我正在使用的类型更大。
我可以通过做像(~0)/n这样的事情来接近我要寻找的答案。然而,当n是2的幂时,这种情况会让我感到不安,因为在这些情况下,计时器需要多走一步才能溢出。
是否有一个简单的表达式,只使用32位整数就能计算出(2^32)/n?
ceil(232 / n)
。考虑两种可能的情况:
n不是2的幂。在这种情况下,n不是232
的因数,除法的上舍入值恰好比下舍入值多1。此外,(使用截断整数除法,例如C或Java),floor(232 / n) == floor((232 - 1) / n)
。所以所需的步骤是(232 - 1)/n + 1
。
n是2的幂。在这种情况下,n恰好是232
的因数,因此(232 - 1) / n
将比232 / n
少一个。因此所需的步骤是(232 - 1)/n + 1
。方便的是,这与第一种情况下的值相同。
n > 216
,则无法保证存在适当的步长。对于较大的n
,上述程序将计算可以保证在第n
步之前不会溢出的最大步长。n
>2^16的步骤上都不会发生“恰好在第n步溢出”的情况。 - greybeardfloor(232 / n) = floor((232 - n) / n + 1)如果您的
n
具有无符号类型(例如uint32_t
),则数学表达式232 - n
可以简单地计算为-n
。uint32_t n = ...;
uint32_t d = (-n) / n + 1;
uint32_t d = (0 - n) / n + 1;
你应该好好记录它,因为这段代码真的很难懂。