Рассмотрим подпрограмму, которая рассчитывается путем последовательных операций деления с остатком.
Начиная с 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;
}