La pregunta sobre cómo emular la división de enteros al estilo de Python y el módulo. Todas las respuestas dadas aquí suponen que los operandos de esta operación son enteros, pero Python también puede usar flotantes para su operación de módulo. Por lo tanto, creo que la siguiente respuesta resuelve el problema aún mejor:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int pydiv(double a, double b) {
int q = a/b;
double r = fmod(a,b);
if ((r != 0) && ((r < 0) != (b < 0))) {
q -= 1;
}
return q;
}
int main(int argc, char* argv[])
{
double a = atof(argv[1]);
double b = atof(argv[2]);
printf("%d\n", pydiv(a, b));
}
Y para el módulo:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
double pymod(double a, double b) {
double r = fmod(a, b);
if (r!=0 && ((r<0) != (b<0))) {
r += b;
}
return r;
}
int main(int argc, char* argv[])
{
double a = atof(argv[1]);
double b = atof(argv[2]);
printf("%f\n", pymod(a, b));
}
He probado los dos programas anteriores en contra de la forma en Python se comporta con el siguiente código de prueba:
#!/usr/bin/python3
import subprocess
subprocess.call(["cc", "pydiv.c", "-lm", "-o", "cdiv"])
subprocess.call(["cc", "pymod.c", "-lm", "-o", "cmod"])
def frange(start, stop, step=1):
for i in range(0, int((stop-start)/step)):
yield start + step*i
for a in frange(-10.0, 10.0, 0.25):
for b in frange(-10.0, 10.0, 0.25):
if (b == 0.0):
continue
pydiv = a//b
pymod = a%b
cdiv = int(subprocess.check_output(["./cdiv", str(a), str(b)]))
cmod = float(subprocess.check_output(["./cmod", str(a), str(b)]))
if pydiv != cdiv:
exit(1)
if pymod != cmod:
exit(1)
Lo anterior comparará el comportamiento de la división y el módulo de Python con las implementaciones C que presenté en 6320 testcases. Dado que la comparación tuvo éxito, creo que mi solución implementa correctamente el comportamiento de Python de las operaciones respectivas de .
Si quiere usar eficientemente una tabla de búsqueda. Si este código es un problema de eficiencia, la única alternativa real sería usar los operadores regulares/y% y vivir con su redondeo. –
Esto es bastante limpio.Sería útil contar con algunos refuerzos en este código (con ese anidamiento condicional, es difícil saber qué está pasando en ...) –
Quizás esto es una cuestión de gusto, pero no estoy de acuerdo con la adición de frenillos haría que esto más fácil de leer Al leer el código, miro la sangría en lugar de contar llaves en mi cabeza. –