A/B = Q, donc A = B * Q. Nous savons tous les deux A & B, nous voulons Q.
Mon idée d'ajouter au mélange: recherche binaire Q. Démarrer avec Q = 0 & Q = 1, peut-être des cas de base. Continuez à doubler jusqu'à ce que B * Q> A, et alors vous avez deux bornes (Q et Q/2), alors trouvez le bon Q entre les deux. O (log (A/B)), mais un peu plus compliqué à mettre en œuvre:
#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;
}
De plus, vous pouvez également itérer les bits, les paramètres un à 1. Si B * Q < = A est vrai, garder le bit comme 1, sinon le remettre à zéro. Passez MSB-> LSB. (Vous devez être en mesure de détecter B * Q va déborder, mais
+1 pour les devoirs d'auto-étiquetage, quelque chose que je n'ai pas vu arriver très souvent jusqu'à présent. – RBerteig