A/B = P, więc A = B * P. Wiemy, że zarówno & B, chcemy Q.
Mój pomysł, aby dodać do mieszanki: Binary wyszukiwania Q. Rozpocznij Q = 0 & Q = 1, może jako przypadkach bazowych. Podwajaj aż do B * Q> A, a następnie masz dwa granice (Q i Q/2), więc znajdź poprawną Q pomiędzy tymi dwoma. O (log (A/B)), ale nieco trudniejsze do wdrożenia:
#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;
}
Dodatkowo, można również iterację bitów ustawienie każdy do 1. Jeżeli B * P < = A jest prawdą trzymaj bit jako 1, w przeciwnym razie zeruj go. Kontynuuj MSB-> LSB. (Musisz być w stanie wykryć B * Q wyleje jednak
+1 za zadanie domowe z samobutowaniem, coś, co do tej pory nie widziałem zbyt często. – RBerteig