Double

Hallo,

ich hatte da ein Problem,
es ist gelöst und wollte mich eigentlich nur ärgern ^^

Also, folgendes:
Ich habe/wollte eine Funktion schreiben bei der Ich ModuloDivision für Doubles „integriere“ und einen 64-bit Integer zurückgibt.+

__int64 DoubleModulo(double x, __int64 y)
{ return (__int64)(y * ((x / y) - floor(x / y))); }

soweit, sogut, doch nach einigen Tests, kam ein Problem zum Vorschein :frowning:
Ich hatte
x = 9999
y = 100

Als Rückgabewert kam bekam ich dann 98, obwohl es doch eigentlich 99 sein müsste :frowning:

Dann habe ich die Funktion um einige Debug-Befehle erweitert:

__int64 DoubleModulo(double x, __int64 y)
{ double a = x / y;
double b = floor(x / y);
double c = y * (a - b);
TRACE(„c = %f\n“, c);
TRACE("(int)c = %d\n", (int)c);
ASSERT(c == (int)c);

return (__int64)(y * ((x / y) - floor(x / y))); }

Ausgabe:
c = 99.000000
(int)c = 98

Desweiteren wurde mir mitgeteilt, das die aussage c == (int)c nicht zutreffend sei !
Auf den Fehler bin ich gestoßen, als ich gesehen habe, das der DEBUGGER(Variablen-Ausgabe) gesagt hat, c = 98.999999999999

Ist eher son kleiner Erlebnisbericht, aber eine Frage stellt sich mir, wie kann ich das umgehen ???

Danke für die Hilfe im voraus.

MfG
DDR-RAM

Hallo,

ich hatte da ein Problem,
es ist gelöst und wollte mich eigentlich nur ärgern ^^

Desweiteren wurde mir mitgeteilt, das die aussage c == (int)c
nicht zutreffend sei !
Auf den Fehler bin ich gestoßen, als ich gesehen habe, das der
DEBUGGER(Variablen-Ausgabe) gesagt hat, c = 98.999999999999

Ist eher son kleiner Erlebnisbericht, aber eine Frage stellt
sich mir, wie kann ich das umgehen ???

Du bist da in eine böse Falle getappt! Die Typen Double und Float gehören nicht zu den skalaren Datentypen, wie beispielsweise int und long. Aus diesem Grund darf man sie auch nicht auf Gleichheit prüfen. Stattdessen musst du prüfen, ob der eine Wert in einem definierten Intervall um den zweiten Wert liegt. Du betrachtest zwei Werte als gleich, wenn die folgende Bedingung erfüllt ist:

(x - epsilon) definiert, DBL_EPSILON kannst du für double verwenden.

Der wortfuchs

Hallo DDR-RAM,

Desweiteren wurde mir mitgeteilt, das die aussage c == (int)c
nicht zutreffend sei !

Die Repräsentation von INTEGER und FLOATINGPOINT Zahlen ist sehr unterschiedlich, deshalb vergleichst du Äpfel mit Birnen.

Auf den Fehler bin ich gestoßen, als ich gesehen habe, das der
DEBUGGER(Variablen-Ausgabe) gesagt hat, c = 98.999999999999

Es gibt halt schon gute Gründe wieso man Integer und FP-Typen implementiert, nicht nur in C.

Ist eher son kleiner Erlebnisbericht, aber eine Frage stellt
sich mir, wie kann ich das umgehen ???

zuerst runden: int(c + 0.0001); (Konstante je nach Bedarf)
Es gibt auch noch die Funktionen floor() und ceil().

MfG Peter(TOO)