Anwendungserzeugen, die falsche Ergebnisse, wenn es einen Ausdruck umwandelt, Verdopplung eingeben, um lange einzugeben.
Zum Anfang
Der Fehler wird von Unterschieden in arithmetischer Genauigkeit verursacht.
Zum Anfang
Die C-- und Die C++-Standards geben an, dass die Nummer zu Null abgeschnitten wird, wenn eine Anwendung eine Gleitzahl zu einer ganzen Zahl konvertiert. Wenn das Runden das bevorzugte Verhalten ist kann die Anwendung 0,5 wie geeignetes hinzufügen oder 0,5 wie geeignetes subtrahieren, so erzielt Kürzung das korrekte Ergebnis. Für diese Zwecke stellt der folgende Text einen Makro dar.
Zum Anfang
Wenn dieses Verhalten mit allem Unverankert kompiliert wird, wird dieses Verhalten in dem folgenden Codebeispiel veranschaulicht Sie verweisen mathematische Option anders als /FPa. Die Anwendung zeigt -4049 als den Wert für Long2 und Long4 an, was es ist falsch. Die Anwendung zeigt den richtigen Wert -4050 für Long1 und Long3 an.
Zum Anfang
Beispielcod
/*
* Compile options needed: /FPc or /FPc87 or /FPi or /FPi87
*/
#include "stdio.h"
main()
{
long val1, val2, val3;
double mul1, mul2;
val1 = 45000;
mul1 = 0.09;
mul2 = (double)val1 * mul1 * -1.00;
printf("%7ld Long1 ", (long)mul2);
val2 = (long)mul2;
printf("%7ld Long2 ", (long)((double)val1 * mul1 * -1.00));
printf("%7ld Long3 ", val2);
val3 =(long)((double)val1 * mul1 * -1.00);
printf("%ld Long4 \n", val3);
}
Die Anwendung führt zu den falschen Ergebnissen, indem die Anwendung einen realen ungeprüften Wert zu einem Long-Wert konvertiert; die Anwendung führt zu korrekten Ergebnissen, indem die Anwendung ein ungeprüftes Real zu einem 8-Bytereal konvertiert und den Wert zu einem Long-Wert konvertiert.
Die Konvertierung eines ungeprüften Reals zu einem 8-Bytereal rundet gemäß den Typenkonvertierungsregeln die Zahl von -4049.99999999999985 zu -4050.0. Die Anwendung konvertiert diesen Wert zu einem Long-Wert den Ergebnissen Wert -4050 wann. Wenn die Anwendung den doppelten Wert zu einem Long-Wert direkt konvertiert, schneidet die Anwendung jedoch zu Null ab. In diesem Beispiel wird -4049.99999999999985 -4049.
Mehr Zahlen (wie .01) wiederholen Brüche in der Nummerierung-Binär-Datei von System, das genau nicht dargestellt werden kann. Beliebige Darstellung dieser Zahlen ist ein wenig mehr oder weniger als dem "echte" Wert. Wenn eine Berechnung einen dieser Werte umfasst wird der Darstellungsfehler weitergegeben und kann vergrößert werden. Nur bei dem Verlieren einer Berechnung von Genauigkeit in einem Zwischen-Wert treten Fehler auf, da der Fehler nur in dem niederwertigesten Teil der Zahl vorhanden ist.
Die Konvertierungen schneiden immer zu Null ab. Der folgende Makro rundet die Zahl effektiv, indem 0,5, das die Zahl in einer Zahl zu einer ganzen Zahl anschließend konvertiert, die Größenordnung der Zahl erhöht.
#define ROUNDL( d ) ((long)((d) + ((d) > 0 ? 0.5 : -0.5)))
Das Problem tritt bei den Microsoft Visual C++ 32-bit-Editionen nicht auf, als Win32 den langen Doubeln-Datentypen aus Gründen von Kompatibilität nicht unterstützt.
Weitere Informationen zu dem Konvertieren von Gleitkommazahlen zu ganzen Zahlen finden Sie in dem Typenkonvertierungsabschnitt des "C Language Reference" Handbuchs.
Zum Anfang