2009-08-22 9 views
0

Mögliche Duplizieren zu verdoppeln:
Floating point inaccuracy examplesErst Rundes Problem beim Konvertieren char [8]

ich einen Char-Array zu konvertieren Ich versuche zu verdoppeln, aber ich habe eine Art von Rundungs bei der letzten Genauigkeit der Dezimalzahl. Bitte beachten Sie den folgenden Code.

#include <stdio.h> 

#define INT32MAX 017777777777 
#define LIND 0 
#define MIND 1 

typedef int Int32; 
typedef unsigned int UInt32; 
typedef short int Int16; 

union _talign 
{ 
    double  _doubles[2]; 
    double  _double; 
    Int32   _long[4]; 
    UInt32  _unsign[4]; 
    Int16   _short[8]; 
    float   _float[4]; 
    char   _char[16]; 
    long long  _BIGINT; 
}; 

int main() 
{ 
    union _talign value; 
    double dval = 0.0; 
    double dmag = 1000000.0000000000; 
    int i=0; 
    char cp[8] = { 135,55,83,03,178,67,55,0}; 

    for(i=0;i<8;i++) 
     value._char[i] = cp[i]; 

    dval = (double)value._long[MIND]; 
    dval = ((double)INT32MAX + 1.0) * dval * 2.0; 
    dval = (dval + value._long[LIND])/dmag ; 

    printf("Expecting dval = 15555555558.111111\n"); 
    printf("Got dval = %lf\n",dval); 

    return 0; 
} 

Ich erwarte dval 15555555558,111111 aber das Programm kehrt mich 15555555558,111113 zu sein. Also, jeder hat eine Idee, um die letzte Genauigkeit richtig zu bekommen oder irgendeine andere Art, diese Art von Umwandlung zu machen. Ihre Vorschläge werden geschätzt. Danke

Antwort

5

Das Problem ist, dass alle Gleitkommazahlen nicht genau in einer endlichen Anzahl von Ziffern dargestellt werden können. Gleitkommatypen tun ihr Bestes, aber in diesem Fall können Sie Ihre bestimmte Nummer nicht genau als double darstellen. 15555555558.111113 ist das Beste, was Sie tun können, es sei denn, Sie greifen auf eine Bibliothek für Dezimalzahlen mit beliebiger Genauigkeit zurück.

2

aus Wikipedia, Accuracy problems

Die Tatsache, dass Gleitkommazahlen nicht getreu die wirklichen Zahlen nachahmen kann, und dass Gleitkommazahlen Operationen können nicht getreu nachahmen wahre arithmetische Operationen, führt zu viele überraschend Situationen. Dies ist bezogen auf die endliche Präzision mit welche Computer im Allgemeinen Zahlen darstellen.

Ein einfaches Beispiel,

double dval = 0.1; 
    printf("dval = %f\n", dval); // 0.1 

Wir sehen 0.1 auf dem Bildschirm. Es scheint in Ordnung, oder?

Lets versuchen, mehr Ziffern angezeigt werden,

printf("dval = %.18f\n", dval); // ? 

Das Problem ist, dass (nicht immer) die Zahl, die wir nicht die Zahl sehen, die wir haben! Zum Beispiel 0.1 wird intern als Approximation gespeichert: 0.1000000000000000055511512...

Read: