Рассмотрим следующее в качестве эталонной реализации:как вычислить (а раз б) делится на с только с использованием 32-битных целочисленных типов, даже если а раз б не поместилась бы такой тип
/* calculates (a * b)/c */
uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c)
{
uint64_t x = a;
x = x * b;
x = x/c;
return x;
}
Меня интересует в реализации (в C или псевдокоде), которая не требует 64-битного целочисленного типа.
Я начал набрасывать реализацию, которая обрисовывает в общих чертах, как это:
/* calculates (a * b)/c */
uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c)
{
uint32_t d1, d2, d1d2;
d1 = (1 << 10);
d2 = (1 << 10);
d1d2 = (1 << 20); /* d1 * d2 */
return ((a/d1) * (b /d2))/(c/d1d2);
}
Но трудность заключается в том, чтобы выбрать значения d1 и d2, которым удается избежать переполнения ((а/d1) * (б/d2) < = UINT32_MAX) и минимизировать ошибку всего расчета.
Любые мысли?
Реализация 64 битное умножение и деление с 32 битной один очевидный способ. Это – AProgrammer
Что вы хотите, чтобы результат не входил в 32 бита? (Например, 'UINT_MAX * UINT_MAX/1') – pmg
@pmg: то же, что и эталонная реализация, верните математический результат по модулю (UINT_MAX + 1). Вот что означает «ссылочная реализация» в моем словаре ;-) –