考虑一个通过连续除法和余数运算进行计数的例程。
从 64 位除数开始,例程除以常数除数。
如果余数为 0,则例程返回。
否则,通过将余数乘以 2^32 并加上整数商来构造新的被除数。
在代码中:
/// ULong - 64 bit, unsigned
/// UInt - 32 bit, unsigned
const UInt Divisor;
int TrickyCounter( ULong Dividend)
{
int count = 0;
Ulong Quotient;
UInt Remainder;
do {
Quotient = Dividend/Divisor;
Remainder = Dividend%Divisor;
assert((Quotient >> 32) == 0);
count = count + 1;
Dividend = ((ULong)Remainder << 32) + Quotient;
} while (Remainder != 0);
return count;
}
对于任意除数,是否有一种最好的非迭代方法来计算必要的股息以获得所需的计数?
对于许多初始股息来说,这似乎很快达到了“断言”条件。一些红利会导致它永远循环吗?
如果例程返回商而不是计数,我可以计算股息以产生我想要返回的数字吗?
Uint TrickyNumber( ULong Dividend, int count)
{
Ulong Quotient = 0;
UInt Remainder;
while (count > 0)
Quotient = Dividend/Divisor;
Remainder = Dividend%Divisor;
assert((Quotient >> 32) == 0);
count = count - 1;
Dividend = ((ULong)Remainder << 32) + Quotient;
}
return (UInt)Quotient;
}