A/B = Q、したがって、A = Bの* Qを。 Q = 0 & Q = 1と バイナリ検索Q.スタートを、おそらくベースの例として:私たちはQ.
私の考えはミックスに追加したい、& Bの両方を知っています。 B * Q> Aになるまで倍増し、2つの境界(QとQ/2)を持っているので、それらの2つの間に正しいQを見つけてください。 O((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;
}
また、あなたはまた、B * Q < = Aがtrueの場合は1にそれぞれ1を設定し、ビットを反復処理することができ、ビットを1のままにしてください。それ以外の場合は0にしてください。 MSB→LSBを進めます。 (ただし、B * Qがオーバーフローすることを検出することができるようにする必要があります
+1セルフタグ付けの宿題については、 – RBerteig