Float formatieren ohne printf

Gast #4498493
Hallo,

ich versuche mir grade eine einfache Umwandlung für floats zu bauen:
1
    double f = 0.245;
2
    
3
    while (f) {
4
        f = f * 10;
5
        int temp = f;
6
        printf("%d", temp);
7
        f = f - temp;
8
    }

Problem ist aufgrund der Eigenart von floats, dass als Ergebnis

245000000000000017763568394002504646778106689453125

herauskommt.

Wie löst printf das Problem?
Gast
Werner schrieb:
> Problem ist aufgrund der Eigenart von floats, dass als Ergebnis
>
> 245000000000000017763568394002504646778106689453125

Viel spannender finde ich die Frage, wie du eine derartige Zahl in eine 
Variable vom Datentyp int reinbekommen hast. Wenn ich mich nicht 
verzählt habe, bräuchtest du dafür ein int mit mindestens 168 Bit.
Das kommt mir - mit Verlaub - etwas exotisch vor.
Wolfgang schrieb:
> Viel spannender finde ich die Frage, wie du eine derartige Zahl in eine
> Variable vom Datentyp int reinbekommen hast

Nein. Er hat nur kein newline drin. Er gibt immer den ganzzahl-wert aus, 
subtrahiert den und multipliziert den Rest mit 10 für die nächste 
stelle. Er will es in einen String umwandeln.
Gast
Moin,

das 'Problem' ist hier weder temp noch printf, das Problem ist die 
Schleife und deren Abbruchbedingung. Die Schleife läuft schlicht durch, 
weil die Abbruchbedingung, so wie Du sie haben möchtest, aufgrund der 
zwangsläufigen Rundungsfehler bei Fließkommazahlen nicht (immer) exakt 
erfasst wird.

Daher nimmt man dafür am besten auch entweder gar keinen float oder 
double, oder wenn doch, dann prüft man auf einen kleinen von Null 
verschiedenen Wert, wenn Null das Ziel des Abbruchs sein soll.

Und die einzelnen Ziffern werden, wie schon erwähnt wurde, als eine 
Zeile ausgegeben, weil Newline \n in printf fehlt.


C ist eine sehr schöne Programmiersprache, mit der man sich auf jede nur 
erdenkliche Art ins Knie schießen kann.


Mit besten Grüßen

Murmelchen
Gast
>Schreib 100 mal an die Tafel:
>"Man darf float nie auf Gleichheit testen!"

Wenn man kurz darüber nachdenkt: 1000 mal!
Warum macht eigentlich ein Compiler keine Warnung bei sowas?

Das hier war der geeignete Fingerzeig:

>Basisfunktionen dafür können fcvt/gcvt/ecvt sein:

http://www.jbox.dk/sanos/source/lib/fcvt.c.html

In meinem Fall kann ich fcvt_r nehmen, wegen Eintrittsinvarianz...

Vielen Dank!

Werner
Gast
Tut er doch, wenn du alle Warnungen aktivierst (was ich per default in 
neuen Projekten immer mache).

-Wfloat-equal
    Warn if floating-point values are used in equality comparisons.

    The idea behind this is that sometimes it is convenient (for the 
programmer) to consider floating-point values as approximations to 
infinitely precise real numbers. If you are doing this, then you need to 
compute (by analyzing the code, or in some other way) the maximum or 
likely maximum error that the computation introduces, and allow for it 
when performing comparisons (and when producing output, but that's a 
different problem). In particular, instead of testing for equality, you 
should check to see whether the two values have ranges that overlap; and 
this is done with the relational operators, so equality comparisons are 
probably mistaken.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.