2016-07-10 5 views
-1

Ich bin nicht sicher, was hier vor sich geht, aber ich habe ein Codebeispiel, das nicht produziert, was ich erwarte, hier ist ein Teil in Frage (nur ein Abschnitt):Grundlegende mathematische Problem in C unter Verwendung von Cygwin

printf("Now enter a Fahrenheit to convert to Centigrade\n"); 
fflush(stdout); 
scanf("%f",&c); 
d = (c-32)*(5/9); 
printf("%f\n",c); 
printf("Your result in Centigrade is %f\n",d); 

Das Ergebnis, wenn ich 212 für die Eingabe einzugeben: Ihr Ergebnis in Grad Celsius 0.000000

ist, wenn ich eine kleine Änderung vornehmen:

printf("Now enter a Fahrenheit to convert to Centigrade\n"); 
fflush(stdout); 
scanf("%f",&c); 
d = (c-32)*5/9; 
printf("%f\n",c); 
printf("Your result in Centigrade is %f\n",d); 

Das Ergebnis jetzt, wenn ich für die Eingabe eingeben 212: Ihr Ergebnis in Centigrad e ist 100.00000, was korrekt ist.

In Mathematik (a + b) * (c/d) ist das gleiche wie (a + b) * c/d; Also, was passiert mit dem Null-Ergebnis nur mit den zusätzlichen Klammern?

+0

Es funktioniert in Java? Bist du sicher? https://ideone.com/gmp86S – MikeCAT

+1

Was ist die Art von 'c'? –

+0

/* Sorry das funktioniert nicht in Java, es leidet das gleiche Problem wie bei C. */ float c = ((a-32) * 5/9); // das funktioniert –

Antwort

3

Da beide Operanden Ganzzahlen sind, ergibt sich 5/9 in 0, da eine ganzzahlige Division durchgeführt wird. Verwenden Sie stattdessen 5./9.

+0

Okay, also werden in C undefinierte Operanden, die durch Klammern gebunden sind, standardmäßig auf den höheren Vorgänger-Datentyp gesetzt? –

+0

@ChristopherKeveny nicht genau. Es gelten "die üblichen arithmetischen Konvertierungen" und dann möglicherweise Integer-Promotions. Siehe http://c0x.coding-guidelines.com/6.3.1.8.html oder noch besser - der c-Standard selbst. –

+0

Nicht nur "in Klammern", sondern immer. –

0

Hier müssen Sie auf zwei Dinge achten.

  1. Operator preceedence
  2. Automatische Typumwandlung

Erstens hat () Betreiber höhere preceedence als * oder / Betreiber.

Zweitens, wenn ein Ausdruck ein float und und int enthält, wird die int automatisch float umgewandelt werden.

Jetzt in Ihrem ersten Fall, was passiert ist:

  1. (c - 32) berechnet wird, (hier 32-32,0 umgewandelt wird und die Berechnung erfolgt). (sagen wir, dies entspricht x)
  2. (5/9) wird berechnet. Hier sind beide Ausdrücke int, also wird nichts in float umgewandelt. Und für int Berechnung, 5/9 entspricht 0. Sagen Sie diesen y
  3. Ihre endgültige Antwort ist gleich wie x * y berechnet wird, und da y0 ist, Ihre Antwort ist 0.0.

jedoch im zweiten Fall, was passiert ist:

  1. (c - 32) berechnet wird, (hier 32-32,0 umgewandelt wird und die Berechnung erfolgt).
  2. (c - 32) * 5 wird berechnet. Hier wird 5 in 5.0 umgewandelt und die Berechnung wird durchgeführt. (sagen wir, dies ist gleich x: x ist Float)
  3. x/9 berechnet wird. Hier wird 9 in 9.0 umgewandelt und die Berechnung erfolgt.

Also, Sie in zweitem Fall sehen können, wurde es nicht mit einem 0 Multiplikation - wie im ersten Fall - daher werden Sie einen von Null bekommen (hoffentlich richtige) Antwort.

+0

Danke sps. Das automatische Hintergrundcasting des Bruchquotienten nach int hat mich erwischt. (int) (5/9) ist tatsächlich Null. –

+0

@ChristopherKeveny: '(5/9)' ist Null auch ohne Besetzung; Beide Operanden sind Ganzzahlen, daher wird die Berechnung mit ganzzahliger Arithmetik durchgeführt. –