trunc() Problem?



  • Hallo Leute,

    Ich schreibe gerade ein sehr einfaches Programm, das die Ziffern in einer realen Nummer zählt, aber es klappt nicht. 😞 Die Ziffern vor dem Komma werden richtig gezählt, aber diese nach dem Komma leider nicht.

    Wenn (n - trunc(n)) ist 0, dann geht der Zyklus weiter. Das kann ich aber nicht verstehen?!?!

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
      double n, nb;
      unsigned p, s = 0;
      printf("Enter n: ");
      scanf("%lf", &n);
      nb = n;
      for(p = 0; n > 1; n /= 10, p++);
      printf("Digits before comma: %i\n", p);
      n = nb - trunc(nb);
      for(s = 0; (n - trunc(n)) > 0; n *= 10, s++);
      printf("Digits after comma: %i\n", s);
    
      system("PAUSE");	
      return 0;
    }
    

    Debug im Zyklus:

    Enter n: 123.123
    Digits before comma: 3
    n = 1.2300000000 trunc(n) = 1.0000000000 / Result: 0.2300000000
    n = 12.3000000000 trunc(n) = 12.0000000000 / Result: 0.3000000000
    n = 123.0000000000 trunc(n) = 123.0000000000 / Result: 0.0000000000
    n = 1230.0000000000 trunc(n) = 1230.0000000000 / Result: 0.0000000000
    n = 12300.0000000005 trunc(n) = 12300.0000000000 / Result: 0.0000000005
    n = 123000.0000000047 trunc(n) = 123000.0000000000 / Result: 0.0000000047
    n = 1230000.0000000466 trunc(n) = 1230000.0000000000 / Result: 0.0000000466
    n = 12300000.0000004660 trunc(n) = 12300000.0000000000 / Result: 0.0000004657
    n = 123000000.0000046500 trunc(n) = 123000000.0000000000 / Result: 0.0000046492
    n = 1230000000.0000465000 trunc(n) = 1230000000.0000000000 / Result: 0.0000464916
    n = 12300000000.0004650000 trunc(n) = 12300000000.0000000000 / Result: 0.0004653931
    n = 123000000000.0046500000 trunc(n) = 123000000000.0000000000 / Result: 0.0046539307
    n = 1230000000000.0466000000 trunc(n) = 1230000000000.0000000000 / Result: 0.0466308594
    n = 12300000000000.4670000000 trunc(n) = 12300000000000.0000000000 / Result: 0.4667968750
    n = 123000000000004.6700000000 trunc(n) = 123000000000004.0000000000 / Result: 0.6718750000
    n = 1230000000000046.7000000000 trunc(n) = 1230000000000046.0000000000 / Result: 0.7500000000
    n = 12300000000000468.0000000000 trunc(n) = 12300000000000468.0000000000 / Result: 0.0000000000
    Digits after comma: 17

    Woher kommen die Ziffern am Ende?? 😮



  • Gegenfrage: Wieviele Nachkommastellen hat 1/3? Wie wird eine Fliesskommazahl gespeichert?

    Jede Rechnung mit Gleitkommazahlen ist mindestens leicht fehlerhaft.



  • 1. Wir sprechen hier nur über konkrete reale Nummern ..
    2. Ich weiß nicht ganz genau wie Fliesskommazahlen gespeichert sind, aber ich vermute, dass es keine solche unbekannte Nummern auftreten sollen nach dem Komma. Das ist ja für mich merkwürding. Es ist total unlogish.

    OK, gibt es eine andere Weise, so dass man die Nummern nach dem Komma einer realen Nummern zählen kann?

    Ich werde mal versuchen Informationen über die Fliesskommazahlen zu finden...



  • itportal schrieb:

    1. Wir sprechen hier nur über konkrete reale Nummern ..

    Was sind "konkrete reale Nummern"? Ich kenne reelle Zahlen, die wiederum in rationale und irrationale Zahlen aufgeteilt sind.

    itportal schrieb:

    2. Ich weiß nicht ganz genau wie Fliesskommazahlen gespeichert sind, aber ich vermute, dass es keine solche unbekannte Nummern auftreten sollen nach dem Komma. Das ist ja für mich merkwürding. Es ist total unlogish.

    http://de.wikipedia.org/wiki/IEEE_754

    itportal schrieb:

    OK, gibt es eine andere Weise, so dass man die Nummern nach dem Komma einer realen Nummern zählen kann?

    Nicht mit Fließkommazahlen arbeiten. Für den einfachen Fall wäre es wohl geschickt einfach nur eine Zahl als String zu betrachten und die nötigen Informationen daraus zu gewinnen.



  • "Кonkrete reale Nummern" :p Solchen Begriff gibst doch nicht. Ich meinte, dass man die reale Nummern durch das Testatur eingibt. Man kann 1/3 nicht eingeben, oder...

    String - ja, das ich eine gute Weise und es klappt, aber ich versuche mal nur double oder float zu benutzen.



  • Damit kommst du sehr schnell zu einem Problem: Erstens ist die Genauigkeit von double durch seine Speichergröße begrenzt. Und zweitens können viele Zahlen nicht als endliche Binärzahl gespeichert werden (0.2 = 1/5 hätte z.B. eine unendliche (periodische) Binärdarstellung).



  • Ja, ja .. gehen wir nicht so tief in der Sache. Ich meine, dass man endliche und genaue Nummern gibt ... wie zb. 123.123, 654.13472, 23857.12312 .. etwas nicht so großes. Und meine Frage war - warum entstehen so einige "Nebenziffern" in der Zahl (Debug oben)?! Oder sie kommen von dem Typ der Daten? Wird das von float und double gemacht oder es gibt einen Fehler in meinem Code?



  • itportal schrieb:

    Und meine Frage war - warum entstehen so einige "Nebenziffern" in der Zahl (Debug oben)?! Oder sie kommen von dem Typ der Daten? Wird das von float und double gemacht oder es gibt einen Fehler in meinem Code?

    Ja, das hängt mit der Speicherung in einem float/double zusammen. Nur wenn deine Zahl sich aus (negativen) Zweierpotenzen zusammensetzen lässt, passt sie exakt in den Speicher (und im Gegensatz zu ganzen Zahlen klappt das nicht immer).



  • Danke vielmals! Eigentlich wuste ich das nicht. Entschuldige für die dumme Frage. 🙄
    Jetzt habe ich zwei schöne e-Bücher gefunden, wo das sehr gut erklärt ist.


Anmelden zum Antworten