Forum: Mikrocontroller und Digitale Elektronik Warum funktioniert float->char Konvertierung nicht korrekt ?


von Frank (Gast)


Lesenswert?

Hallo Forum,

ich brauche für mein µC - Projekt eine Möglichkeit float->char* zu 
konvertieren. In der stdio.h gibt es ja z.B. sprintf, was aber mein C30 
Compliler nicht bietet.

Es ist ja auch egal. Ich habe mir selbst ein Programm geschrieben, 
welches mir die Konvertierung für beliebig viele Stellen macht.

Allerdings funktioniert es nicht immer korrekt. Wenn ich 0,015 in char 
konvertiere, bekomme ich '0'',''0''1''4''9''9' heraus ? Viele andere 
Zahlen gehen wieder wunderbar. Es gibt eben einige Ausnahme, wie z.B. 
0,015 oder 0,01.

Vielleicht weiß jemand die Ursache ?


Hier der Code:
1
#include <iostream>
2
#include <string.h>
3
#include <stdio.h>
4
using namespace std;
5
6
int main(void)
7
{
8
     float f=0.015;       //zu konvertierende float Zahl
9
     int i=0;
10
     int j=0;
11
     int k=0;
12
     int NO=1;  
13
       
14
     char c[10];
15
     
16
     if(f<0)                   //Vorzeichenkontrolle
17
     {      c[i]='-';
18
            f*=-1;
19
            i++;
20
     }
21
     else
22
     {
23
         c[i]='+';
24
         i++;
25
     }
26
     
27
     while(1)                 //Zerlegung
28
     {
29
       if(f/10.0<1.0)
30
       {
31
          c[i]=(int)f%10+48;   //Offset von 48 - ASCII
32
          i++;
33
          for(j=0;j<9;j++)     //Komma bereits gesetzt ?
34
          {
35
             if(c[j]=='.') NO=0;
36
          }
37
          if(NO && k==0)
38
          {
39
          c[i]='.';
40
          i++;
41
          }
42
          if(k!=0)
43
          k--;
44
          
45
          f=f-((int)f%10);
46
          f*=10;
47
       }
48
       
49
       else 
50
       {
51
       f/=10.0;
52
       k++;
53
       }
54
       
55
       if(i==8) break;
56
     }                  
57
     
58
     char* str = &c[0];
59
     cout<<"\n"<<c[0]<<c[1]<<c[2]<<c[3]<<c[4]<<c[5]<<c[6]<<c[7];
60
     
61
     cin>>f;
62
     return 0;
63
}

Ich bin keiner, der effiziente Algorithmen programmiert, aber mein Code 
funktioniert meistens :) Also bitte nicht aufregen, wenn ich es zu 
umständlich mache oder den Wald vor lauter Bäumen übersehe.

MfG
Frank

von Peter (Gast)


Lesenswert?

in float lässt sich leider eine 0.015 nicht darstellen, dein µC hat nach 
der zuweisung eine 0.0.14999999999999 gespeichert. Musst also auf die 
anzahl stellen runden die du ausgeben willst. Das ganze ist ein 
generelles Problem mit float.

von lkmiller (Gast)


Lesenswert?

>...in float lässt sich leider eine 0.015 nicht darstellen...

Wenn ich sowas in MSVC++ schreibe:
1
   float flt1=0.014999999;
2
   float flt2=0.015;
3
4
   printf("%f  %f",flt1, flt2);

dann kommt heraus:
  0.01500  0.01500

Wie denn dann das?

von Karl H. (kbuchegg)


Lesenswert?

lkmiller wrote:
>>...in float lässt sich leider eine 0.015 nicht darstellen...
>
> Wenn ich sowas in MSVC++ schreibe:
>
1
>    float flt1=0.014999999;
2
>    float flt2=0.015;
3
> 
4
>    printf("%f  %f",flt1, flt2);
5
>
>
> dann kommt heraus:
>   0.01500  0.01500
>
> Wie denn dann das?

Weil printf bei der Ausgabe selbst rundet.

Probier mal:

   printf("%.6f  %.6f",flt1, flt2);

von Frank (Gast)


Lesenswert?

Na klasse.

Gibt es eine Funktion, die unmittelbar floats runden kann ?
Also man gibt die Anzahl der Stellen vor ?

Danke für eure Beiträge.

von Peter (Gast)


Lesenswert?

wird wohl schlecht gehen, wenn die funktion wieder float zurückliefert 
hast du das gleiche wie vorher.

von Frank (Gast)


Lesenswert?

Hast recht.

von Peter (Gast)


Lesenswert?

und wenn du es in int wandelst?

also die round(0.014999999 * 10000000) und dann hast du 150000 - wenn du 
die ausgabe eh selber machst braucht du bloss noch das komma richtig zu 
setzten

von Simon K. (simon) Benutzerseite


Lesenswert?

Peter wrote:
> und wenn du es in int wandelst?
>
> also die round(0.014999999 * 10000000) und dann hast du 150000 - wenn du
> die ausgabe eh selber machst braucht du bloss noch das komma richtig zu
> setzten

Bei mir ergibt das 149999,99 und als int umgewandelt 149999

von Hans W. (hans_wurst)


Lesenswert?

Das ist echt komisch.

Kann eigentlich jemand erklären warum man mit float keine 0.015 
darstellen kann? Ist doch schließlich eine Zahl wie jede andere.

Danke für Antworten.

von Peter (Gast)


Lesenswert?

das round() war mit absicht drin

das Problem ist das binäre zahlensystem.
Im Dezimalen System kann man auch nicht 1/3 genau darstellen.

Finde jetzt leider keien gute Erklärung aber hier sind mehr Infos
http://de.wikipedia.org/wiki/IEEE_754

von Simon K. (simon) Benutzerseite


Lesenswert?

Peter wrote:
> das round() war mit absicht drin

Und was macht round? Runden auf wieviel Stellen? Jaja... Oder meinst 
du damit, dass die Nachkommastellen korrekt gerundet werden?

von Peter (Gast)


Lesenswert?

also das round sollte auf INT runden, also auf 0 stellen

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.