Float formatieren ohne printf

Gast #4498493
Lesenswert?
• ▲
▼
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 #4498501
Lesenswert?
• ▲
▼
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.
Gast #4498647
Lesenswert?
• ▲
▼
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 #4498883
Lesenswert?
• ▲
▼
>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 #4498932
Lesenswert?
• ▲
▼
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren