La domanda è stata posta su come emulare la divisione integer e il modulo in stile Python. Tutte le risposte qui fornite presuppongono che gli operandi di questa operazione siano interi, ma Python può anche usare float per la sua operazione modulo. Quindi, penso che la seguente risposta risolve il problema ancora meglio:
#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));
}
E per il modulo:
#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));
}
ho testato i due programmi di cui sopra nei confronti di come Python si comporta utilizzando il seguente codice di prova:
#!/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)
Quanto sopra confronterà il comportamento della divisione e del modulo Python con le implementazioni C presentate in 6320 testicoli. Dal momento che il confronto è riuscito, credo che la mia soluzione implementa correttamente il comportamento di Python delle rispettive operazioni .
Se si desidera utilizzare in modo efficiente una tabella di ricerca. Se questo codice è un problema di efficienza, l'unica vera alternativa sarebbe utilizzare gli operatori regolari/e% e vivere con il loro arrotondamento. –
Questo è abbastanza pulito.Sarebbe utile avere alcune parentesi in questo codice (con quella numerazione molto condizionale, è difficile dire cosa sta succedendo dove ...) –
Forse è una questione di gusti, ma non sono d'accordo che l'aggiunta di parentesi renderebbe questo più facile da leggere. Durante la lettura del codice, guardo la rientranza invece di contare le parentesi graffe nella mia testa. –