A/B=Q なので、A=B*Q です。A と B の両方を知っているので、Q が必要です。
ミックスに追加する私のアイデア: 二分探索 Q. おそらく基本ケースとして、Q=0 & Q=1 から始めます。B * Q > A になるまで 2 倍し続けると、2 つの境界 (Q と Q/2) が得られるので、それらの 2 つの間で正しい Q を見つけます。O(log(A/B)) ですが、実装は少しトリッキーです:
#include <stdio.h>
#include <limits.h>
#include <time.h>
// Signs were too much work.
// A helper for signs is easy from this func, too.
unsigned int div(unsigned int n, unsigned int d)
{
unsigned int q_top, q_bottom, q_mid;
if(d == 0)
{
// Ouch
return 0;
}
q_top = 1;
while(q_top * d < n && q_top < (1 << ((sizeof(unsigned int) << 3) - 1)))
{
q_top <<= 1;
}
if(q_top * d < n)
{
q_bottom = q_top;
q_top = INT_MAX;
}
else if(q_top * d == n)
{
// Lucky.
return q_top;
}
else
{
q_bottom = q_top >> 1;
}
while(q_top != q_bottom)
{
q_mid = q_bottom + ((q_top - q_bottom) >> 1);
if(q_mid == q_bottom)
break;
if(d * q_mid == n)
return q_mid;
if(d * q_mid > n)
q_top = q_mid;
else
q_bottom = q_mid;
}
return q_bottom;
}
int single_test(int n, int d)
{
int a = div(n, d);
printf("Single test: %u / %u = %u\n", n, d, n / d);
printf(" --> %u\n", a);
printf(" --> %s\n", a == n / d ? "PASSED" : "\x1b[1;31mFAILED\x1b[0m");
}
int main()
{
unsigned int checked = 0;
unsigned int n, d, a;
single_test(1389797028, 347449257);
single_test(887858028, 443929014);
single_test(15, 5);
single_test(16, 4);
single_test(17, 4);
single_test(0xFFFFFFFF, 1);
srand(time(NULL));
while(1)
{
n = rand();
d = rand();
if(d == 0)
continue;
a = div(n, d);
if(n / d == a)
++checked;
else
{
printf("\n");
printf("DIVISION FAILED.\n");
printf("%u / %u = %u, but we got %u.\n", n, d, n / d, a);
}
if((checked & 0xFFFF) == 0)
{
printf("\r\x1b[2K%u checked.", checked);
fflush(stdout);
}
}
return 0;
}
さらに、各ビットを 1 に設定して、ビットを反復処理することもできます。B * Q <= A が true の場合、ビットを 1 のままにし、それ以外の場合はゼロにします。MSB→LSBと進みます。(ただし、B*Q がオーバーフローすることを検出できる必要があります。