usted menciona que usted tiene que probar casi divisibilidad con . La siguiente teoría debería ser cierto para las pruebas a corto divisibilidad contra potencias de dos:
#define THRESHOLD 0.11
int nearly_divisible(float f) {
// printf(" %f\n", (a - (float)((long) a)));
register long l1, l2;
l1 = (long) (f + THRESHOLD);
l2 = (long) f;
return !(l1 & 31) && (l2 & 31 ? 1 : f - (float) l2 <= THRESHOLD);
}
Lo que estamos haciendo es coaccionar el flotador, y el flotador + UMBRAL a tiempo.
f (long) f (long) (f + THRESHOLD)
63.9 63 64
64 64 64
64.1 64 64
Ahora comprobamos si (largo) f es divisible con 32. Sólo tienes que comprobar los menores cinco bits, si se ajustan a cero, el número es divisible por 32. Esto conduce a una serie de falsos positivos : 64.2 a 64.8, cuando se convierte a largo, también son 64, y pasarían la primera prueba. Por lo tanto, verificamos si la diferencia entre su forma truncada yf es menor o igual que UMBRAL.
Esto, también, tiene un problema: f - (flotación) l2 < = UMBRAL sería válido para 64 y 64.1, pero no para 63.9. Por lo tanto, agregamos una excepción para números menores que 64 (que, cuando se incrementa por UMBRAL y posteriormente se coacciona para indicar por mucho tiempo que la prueba en discusión debe ser inclusiva con la primera prueba, es divisible por 32), al especificar que los 5 bits inferiores no son cero. Esto se aplicará a 63 (1000000 - 1 == 1).
Una combinación de estas tres pruebas indicaría si el número es divisible por 32 o no. Espero que esto esté claro, por favor perdona mi extraño inglés.
Acabo de probar la capacidad de extensión a otras potencias de tres - los siguientes números de programa imprime entre 383,5 y 388,4 que son divisibles por 128.
#include <stdio.h>
#define THRESHOLD 0.11
int main(void) {
int nearly_divisible(float);
int i;
float f = 383.5;
for (i=0; i<50; i++) {
printf("%6.1f %s\n", f, (nearly_divisible(f) ? "true" : "false"));
f += 0.1;
}
return 0;
}
int nearly_divisible(float f) {
// printf(" %f\n", (a - (float)((long) a)));
register long l1, l2;
l1 = (long) (f + THRESHOLD);
l2 = (long) f;
return !(l1 & 127) && (l2 & 127 ? 1 : f - (float) l2 <= THRESHOLD);
}
parece funcionar bien hasta ahora!
+1 Esta es una solución muy razonable si no tiene disponible la función 'remainder'. –
o: else if (32.0f - offset
quinmars