C++ Programm zur Berechnung des Volumens einer Kugel

jan002

Lt. Junior Grade
Registriert
Juli 2009
Beiträge
321
Hallo,
ich habe folgendes Programm, nur leider funktioniert es nur wenn ich das ,,hoch 3'' weglasse.
Kann mir jemand sagen woran es liegt?

#include<stdio.h>
#include<math.h>

int main()
{
float d;
float p = M_PI;


printf ("Bitte geben Sie den Durchmesser der Kugel ein (in cm)\n");
scanf (" %f", &d);
_flushall();


printf ("\n Das Volumen beträgt %f cm^3", p*d^3/6);


getchar ();
getchar ();
return 0;

}
 
Code:
#include <math.h>
...

pow(x,3)

Das Zeichen ^ ist glaube eine Bit-Operation. Jedenfalls kein Rechenoperator.
 
Bevor hier noch weiter geglaubt und gerätselt wird, hier des Rätsels Lösung.

^ ist der bitweise Exklusiv-Oder-Operator - auch XOR genannt.
 
Außerdem ist der %f Format Specifier für double, nicht für float. Das betrifft sowohl scanf als auch printf.
 
Außerdem ist der %f Format Specifier für double, nicht für float. Das betrifft sowohl scanf als auch printf.
Meine Erfahrung ist dass sich hier leider nicht jeder Bibliothek an die Standards hält. %f sollte float sein, %lf (long float) ist der double. Das kann man am besten nur ausprobieren. Wichtiger ist, dass - wenn du Berechnungen direkt in den printf-Aufruf schreibst - auch sicher der korrekte Rückgabewert aus der Berechnung kommt, sonst passt der Stack nicht mehr, da der compiler die Arg-Listen nicht nach Datentyp auflösen kann. und von dem %f im String weiß er auch nix Schreib am besten noch einen (float)-cast rein, das müsste dann so aussehen:
Code:
printf ("\n Das Volumen beträgt %f cm^3",(float) p*pow(d,3.)/6.);
Jetzt ist es eindeutig. Hab schon diverse dumme Fehler gehabt deswegen, weil der Compiler als Parameter dann lieber einen double verwendet hat.
 
7H3 N4C3R schrieb:
Außerdem ist der %f Format Specifier für double, nicht für float. Das betrifft sowohl scanf als auch printf.

Wetten würde ich darauf nicht! Meine Erfahrung gleicht der von dazpoon. %lf ist double, %f float.

%u - unsigned int
%d - dezimal
%c - char
%p - pointer
%x - hexadezimal
%s - string

und eben

%f - float
 
ASCII ist 7 Bits lang, in 0xFC ist das 8. Bit gesetzt (0x80, 128) - ergo is das kein ASCII Zeichen mehr und kann auf jedem Terminal anders aussehen.
 
Mittlerweile sollte jedes Terminal (außer der cmd.exe-Dreck von Windows) Unicode-fähig sein.
 
XunnD schrieb:
Wetten würde ich darauf nicht! Meine Erfahrung gleicht der von dazpoon. %lf ist double, %f float.
Ich hatte es vor meiner Antwort extra im C-Standard nachgeschlagen.

Allerdings bezieht sich das nur auf fprintf, wie ich jetzt auch festgestellt habe (hatte nicht bis fscanf gelesen, sondern bei fprintf aufgehört):
%f ist double, %Lf (Achtung, case) ist long double. Vom l(ell)-Modifier (also %lf) wird bei fprintf explizit erwähnt, dass er keinen Einfluss hat.
Nachzulesen unter 7.19.6.1, Satz 8 und 7.

Bei fscanf erwartet %f tatsächlich ein float und bei %lf ein double.
Im Standard steht zu %f nur lapidar "The corresponding argument shall be a pointer to floating." (7.19.6.2, Satz 12). Allerdings steht beim l(ell)-Modifier, dass dann ein double erwartete wird. long double bekommt man mit dem L-Modifier (7.19.6.2, Satz 11).
Das Beispiel unter 7.19.6.2, Satz 17/18 verdeutlicht auch, dass tatsächlich float gemeint ist.

Finde ich insgesamt gerade etwas inkonsistent... *confused*

(achso: printf entspricht fprintf mit stdout als erstem Argument, scanf entspricht fscanf mit stdin als erstem Argument)


Edit:
Gerade selbst dazugelernt: Der Grund für die "Anomalie" von %f in fprintf ist, dass in einer Ellipse (...) in der Argumentliste jeder float automatisch zu double umgewandelt wird. Bei Pointern (bei fscanf) ist das natürlich nicht der Fall, da man ja einen Pointer auf float und keinen Float selbst hat. Steht unter 6.5.2.2, Satz 8.
Ein expliziter Cast nach float ist also insofern wirkungslos, weil der Wert danach direkt wieder in einen Double umgewandelt wird. Höchstens die Präzision könnte davon beeinflusst werden, was üblicherweise aber trotzdem nicht passiert, weil Compiler i.d.R. den Wert einfach im Register behalten. Beim GCC lässt sich die Rundung aber mit -fstore-floats IEEE-konform erzwingen.

Und noch ein Edit:
Aus den FAQ von comp.lang.c zu scanf (da steht nochmal das gleiche drin):
http://c-faq.com/stdio/scanf2.html
http://c-faq.com/stdio/scanfvsprintf.html

Hm und das Ursprungsprogramm war hinsichtlich %f also doch richtig. Sorry. :schaf: :mussweg:
 
Zuletzt bearbeitet:
Puh, jetzt bin ich auch schlauer. Das ist ja schon ein ziemliches Hin und Her.
 
Zurück
Oben