Hier ist ein Code:
%Vor% Was 1000000000000000002
zurückgeben soll, wenn ich 1000000000000000000
und 2
eingib.
Wenn ich es mit cmath
versuche, gibt es 1000000000000000000
zurück, aber wenn ich cstdlib
verwende, wird 1000000000000000002
zurückgegeben. Warum passiert das überhaupt?
Auch wenn ich bedenke, dass ich cmath verwende, sollte es nicht noch besser funktionieren?
Ich benutze Linux Mint 18.2 64bit, Eclipse-Plattform.
Die cmath-Version ist eine Float-Eins . Wenn Sie also nur diesen haben, führen Sie die Berechnung tatsächlich auf Gleitkommazahlen durch und konvertieren am Ende wieder in eine long long
. Float Precision reicht nicht aus, um 18 Ziffern zu speichern, die +2 geht einfach verloren.
Die cstdlib-Version ist eine Ganzzahl . Welche gibt das erwartete Ergebnis.
Wie in den Kommentaren erwähnt, definiert cmath in C ++ 11 auch eine Version von abs
, die ganze Zahlen annimmt. "diese Überladungen werfen jedoch vor den Berechnungen effektiv x auf ein Doppeltes um (definiert, dass T ein ganzzahliger Typ ist)" .
Ich glaube, Ihr Compiler sollte Ihnen eine Warnung für die Konvertierungen geben, wenn Sie -Wall -Wextra
oder ähnliche Flags verwenden, während nur cmath enthalten ist.
Wenn Sie g ++ verwenden, versuchen Sie, beide Versionen mit -Wconversion
(oder -Wfloat-conversion
) zu kompilieren.
Beachten Sie, dass die <cmath>
Version eine Warnung generiert:
main.cpp: 14: 7: warning : Umwandlung in 'long long int' von '__gnu_cxx :: __ enable_if :: __ type {aka double}' kann seinen Wert ändern [-WFloat-Konvertierung] c = abs (a) + abs (b);
Während die <cstdlib>
version ohne Warnungen kompiliert wird.
Das liegt daran, dass <cmath>
in abs()
als 1 definiert ist :
In 1 Die Ganzzahlversionen von <cstdlib>
ist dies als 1 : abs()
sind in <cmath>
seit C ++ 17 definiert.