2017-01-27 11 views
-1

Ich wurde beauftragt, printf in C ohne externe Bibliotheken neu zu erstellen. Ich versuche% f-Funktionalität mit einer Genauigkeit von 6 Dezimalstellen zu implementieren. Also grundsätzlich, wenn ich 15.2554 in die printf-Funktion übergebe, sollte "15.255400" gedruckt werden. Stattdessen wird "15.255399" gedruckt. Mein Code, um die Dezimalstellen zu finden als solche implementiert:Rundungsfehler beim Konvertieren von Double in Char

print_function(double input){ 

    int i = 0; 
    int temp; 
    double temp_dub; 
    char temp_char; 

    temp = (int)input; 

    temp_dub = input - temp; 

    while (i < 6){ 

    temp_dub = temp_dub * 10; 
    temp = (int) temp_dub; 
    temp_char = (char) (temp+48) 

    write(1,&temp_char,1); 
    i++; 

    temp_dub -= (int) temp_dub; 
    } 

    return; 
} 

Kann jemand bitte beleuchten mir, warum ich nicht in der Lage, die nachgestellten Nullen zu erhalten und stattdessen diese Zahl nur leicht unter meinem Eingang von 15,554?

+1

'C' und' C++ 'sind ** verschiedene ** Sprachen. Ein Tag wird eindeutig nicht benötigt. – Ari0nhh

+0

Ihre Funktion zeigt Müll für 15.554 an. Stellen Sie sicher, dass Sie das richtige Code-Snippet gepostet haben. – DyZ

+0

Dieser Code könnte in C oder C++ funktionieren, wenn ich mich nicht irre. – Heisenberg

Antwort

2

Der Wert 15.2554 ist nicht als binary64 darstellbar (IEEE-754 double). Sie können es sehen, wenn Sie die Eingabe mit genügend Ziffern drucken:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
// I took the liberty to implement Ari0nhh's changes here 
void print_function(double input){ 
    int i = 0; 
    int temp; 
    double temp_dub; 
    char temp_char; 

    temp = (int)input; 
    temp_dub = input - temp; 

    while (i < 6){ 
    temp_dub = temp_dub * 10; 
    temp = (int) temp_dub; 
    temp_char = (char) (temp + 48); 
    write(1,&temp_char,1); 
    i++; 
    temp_dub -= (int) temp_dub; 
    } 
} 

int main(int argc, char **argv){ 
    double input; 
    if(argc != 2){ 
    fprintf(stderr,"Usage: %s float\n",argv[0]); 
    exit(EXIT_FAILURE); 
    } 
    // checks omitted 
    input = strtod(argv[1],NULL); 
    printf("INP %.20g\n",input); 
    print_function(input); 
    putchar('\n'); 
    exit(EXIT_SUCCESS); 
} 

Sie, dass 15.2554 Druck als 15.255399999999999849 sehen. Also müssen Sie hier manuell runden, sorry.

+0

Okay, das macht Sinn, aber wie wäre es dann, wenn ich versuche, die printf-Funktion selbst zu schreiben? Woher soll ich wissen, dass ich nur 4 Präzisionsplätze bekomme und die letzten beiden runden muss, wenn die Binärzahl mehr Präzision zeigt? – Heisenberg

+1

Sie können nicht, dass Informationen verloren gehen. Was Sie tun können, ist, die 7. Ziffer und die Runde immer zu überprüfen (in dem von Ihnen bevorzugten Rundungsmodus). – deamentiaemundi

+0

Vielen Dank für die Beantwortung und nicht das Nit-Picking darüber, ob ich die Dinge richtig markiert habe oder nicht! – Heisenberg