PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ Double-Division



fuzzi
07-04-2009, 11:24
hallo,
habe ein problem, das mich langsam zur verzweiflung treibt: also, ich führe folgendes programm aus:


#include <iostream>

int f(double a, double b) {

int x = a/b;
std::cout << a << " " << b << std::endl;
return x;
}

int main(int argc, char** argv)
{
double a(1.0), b(0.01);
int x = f(a,b);
std::cout << x << std::endl;
return 0;
}

eigentlich müsste jetzt x = 100 sein, ist es auch, wenn ich das "cout a b" in der funktion f auskommentiere. wenn ich den code aber wie oben, mit dem cout in f ausführe, ist x = 99

ich kann mir das einfach nicht erklären.. woran liegt das? danke für eure hilfe!
(kompiliert unter ubuntu mit g++)

anda_skoa
07-04-2009, 14:00
Vielleicht kommt ein Kompileroptimierungsschritt nicht zum Zuge, etc.

Probier mal das Ergebnis zunächst einer double Variabe zuzuweisen und erst dann zu casten/runden.

Ciao,
_

fuzzi
07-04-2009, 14:14
vielen dank, du hattest recht, es lag an beidem, was du geschrieben hast. ich habe vorher mit -O3 kompiliert, wenn ich das weglasse und außerdem

double y = a/b;
int x = y;
schreibe, dann gehts.

Allerdings geht

double x = a/b
ohne den zwischenschritt auch ohne -O3 nicht.

verstehe leider überhaupt nicht, warum sich das so verhält. kannst du dir da einen reim drauf machen?

fuzzi
07-04-2009, 16:07
mittlerweile wirds mir echt unheimlich. habe jetzt die cpp-Datei auf einem anderen Rechner kompiliert (mit g++ (GCC) 4.2.1 (SUSE Linux)) und die ergebnisse sind richtig, mit und ohne Optimierungsoption O3.

(eigentlich gehts um eine größere quelldatei, in der das oben beschriebene problem an verschiedenen stellen auftritt (in konstruktoren usw.)

kompiliere ich die allergleiche Datei auf meinem laptop (mit g++ (Ubuntu 4.3.2-1ubuntu12) 4.3.2) wird an verschiedenen stellen falsch dividiert.

das gibts doch gar nicht, woran kann das liegen?

anda_skoa
08-04-2009, 06:44
Könnte ein Fehler im Compiler sein.

Falls deine Divisionen nicht immer ganzzahlige Ergebnisse liefern, du also als Resultat runden willst, ist es vermutlich besser es so zu machen



double y = a/b;
if (y < 0.0) y -= 0.5;
else y += 0.5;
int x = y;


Ciao,
_

undefined
08-04-2009, 09:34
In deinem Beispiel Rechnest du 1/0, (Mein Compiler sagt Gleitkomma-Ausnahme) macht also wenig sinn.
Oder verwende die math funktionen um den Restwert von double werten zu erhalten.

// g++ -O4 -Wall -W -Wextra -pedantic d.cpp -o test

#include <iostream>
#include <cmath>

int f(double a, double b)
{
std::cout << a << " " << b << std::endl;
return fmod(a,b);
}

int main(int, char**)
{
double a(1.0), b(0.01);
int x = f(a,b);
std::cout << x << std::endl;
return 0;
}

peschmae
08-04-2009, 17:21
In deinem Beispiel Rechnest du 1/0, (Mein Compiler sagt Gleitkomma-Ausnahme) macht also wenig sinn.

Nein, gerechnet wird ja noch mit den (nicht auf Ganzzahlen gerundeten) doubles. Erst das Ergebnis wird bei der Zuweisung nach int konvertiert...

MfG Peschmä