Forum: Compiler & IDEs ASCII-Char to float


von TechInfo (Gast)


Lesenswert?

Nachdem mir hier sehr geholfen wurde beim Umwandeln von int- und 
float-Werten in char, bräuchte ich nun noch ein Funktion die den 
umgekehrten Weg geht, also ein char in float bzw. char in int umwandelt. 
atof liefert bei meinem Compiler leider immer nur die letzte Stelle aus 
dem char array.

Ich habe zunächst daran gedacht, die in meinem anderen Thread von Karl 
heinz Buchegger gepostete Funktion umzukehren. Also Zerlegung des 
Strings in einzelne Zeichen, dann Abzug von '0'. Nur, wie füge ich die 
einzelnen Zahlen dann wieder zusammen?

Gibt es noch eine andere Lösung?

von Karl H. (kbuchegg)


Lesenswert?

Hinweis:

  53 =   10 * 5 + 3


und genauso baut man eine Zahl wieder zusammen

   Result = 0;
   while( *s1 != '\0' ) {    // nächstes Zeichen

     Result = 10 * Result + ( *s1 - '0' );
     s1++;
   }

  '5' '8' '3'

  Result = 0;

  Result = 10 * Result + ( '5' - '0' ) = 10 * 0 + 5 = 5
  Result = 10 * Result + ( '8' - '0' ) = 10 * 5 + 8 = 58
  Result = 10 * Result + ( '3' - '0' ) = 10 * 58 + 3 = 583




von TechInfo (Gast)


Lesenswert?

Sehr geil. Das ist ja einfacher als ich gedacht habe.

Ich muss aber Vor- und Nachkommaanteil getrennt betrachten, oder?

Und zwischendurch eine Abfrage, ob das aktuelle Zeichen der Punkt ist.

von Karl H. (kbuchegg)


Lesenswert?

TechInfo wrote:
> Sehr geil. Das ist ja einfacher als ich gedacht habe.
>
> Ich muss aber Vor- und Nachkommaanteil getrennt betrachten, oder?
>
> Und zwischendurch eine Abfrage, ob das aktuelle Zeichen der Punkt ist.

Yep.
Nachkommaanteil ist aber blöder.
Da brauchst du eine Hilfsvariable (float), die du immer
durch 10 dividierst

  0.8765 =

  8 * 0.1     +
  7 * 0.01    +
  6 * 0.001   +
  5 * 0.0001

(Drum wundert es mich ja, dass diese Bibliotheksfunktionen
nicht richtig funktionieren. Das alles ist dermassen
simpel)

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger wrote:

> (Drum wundert es mich ja, dass diese Bibliotheksfunktionen
> nicht richtig funktionieren. Das alles ist dermassen
> simpel)

Den letzten Satz nehme ich zurück.
Wenn man mit floating point arbeitet, kann einem die
Rundungsungenauigkeit zu schaffen machen. 0.1 ist
auf einem Computer im Binärsystem nicht exakt darstellbar,
so dass bei der Behandlung von Nachkommastellen schon
ein gewisses Problem auftaucht.

Aber ansonsten: Die Integer Funktionen braucht der Compiler
für sich selbst (zb. zum Parser von Zahlen im Quelltext).
Legt man den üblichen Ansatz eines Bootstrap-Compilers
zugrunde (Compiler ist in der Lage seinen eigenen Quell-
text zu übersetzen und lauffähig zu machen), dann dürfte
der Compiler eigentlich nicht funktionieren.

von Falk B. (falk)


Lesenswert?

@  Karl heinz Buchegger

>Wenn man mit floating point arbeitet, kann einem die
>Rundungsungenauigkeit zu schaffen machen.

Ja, aber . . .

> 0.1 ist auf einem Computer im Binärsystem nicht exakt darstellbar,

Das wage ich zu bezweiflen.

0.1 = 3D CC CC CD (IEEE 754.b)

MfG
Falk

von TechInfo (Gast)


Lesenswert?

Da es sich ja um einen Softcore handelt, der von der im FPGA designten 
Umgebung abhängig ist in die er eingebettet ist, könnte durchaus auch 
hier der Fehler liegen. Andere Funktionen aus der stdlib oder stdio 
funktionieren ja einwandfrei. Das FPGA-Design habe ich aber nicht selbst 
gemacht.

Nochmal zur Funktion:

Also in Deine while-Schleife baue ich eine if-Anweisung ein, die den 
Punkt abfragt. Wenn der Punkt erreicht ist, wird für die nächsten 
Zeichen die Nachkomma-Bearbeitung wie oben beschrieben durchgeführt. 
SPeichere ich dann den Nachkommaanteil in eine extra Variable, die ich 
dann am Ende zum Vorkommaanteil addiere?

von Karl H. (kbuchegg)


Lesenswert?

TechInfo wrote:
> Da es sich ja um einen Softcore handelt, der von der im FPGA designten
> Umgebung abhängig ist in die er eingebettet ist, könnte durchaus auch
> hier der Fehler liegen. Andere Funktionen aus der stdlib oder stdio
> funktionieren ja einwandfrei. Das FPGA-Design habe ich aber nicht selbst
> gemacht.
>
> Nochmal zur Funktion:
>
> Also in Deine while-Schleife baue ich eine if-Anweisung ein, die den
> Punkt abfragt. Wenn der Punkt erreicht ist, wird für die nächsten
> Zeichen die Nachkomma-Bearbeitung wie oben beschrieben durchgeführt.
> SPeichere ich dann den Nachkommaanteil in eine extra Variable, die ich
> dann am Ende zum Vorkommaanteil addiere?

Nein am einfachsten sind 2 Schleifen:
Die eine beschäftigt sich nur mit dem Vorkommaanteil
und wird verlassen wenn:
* die Zahl zu Ende ist
* oder ein '.' auftaucht
dann gehts in die 2-te (oder auch nicht wenn die Zahl schon
zu Ende war).

von Karl H. (kbuchegg)


Lesenswert?

Falk Brunner wrote:
> @  Karl heinz Buchegger
>
>>Wenn man mit floating point arbeitet, kann einem die
>>Rundungsungenauigkeit zu schaffen machen.
>
> Ja, aber . . .
>
>> 0.1 ist auf einem Computer im Binärsystem nicht exakt darstellbar,
>
> Das wage ich zu bezweiflen.
>
> 0.1 = 3D CC CC CD (IEEE 754.b)

Das wäre mir jetzt aber neu, dass es eine exakte
Repräsentierung für 0.1 gibt. Meines Wissen mündet
0.1 in einen periodischen Dezimalbruch:

0.1 = 1/10 ~ 2^-4 + 2^-5 + 2^-8 + 2^-9 + 2^-12 + 2^-13 + ...

... ein kurzer Google Check scheint das auch zu bestätigen.

von Falk B. (falk)


Lesenswert?

@ Karl heinz Buchegger

>Das wäre mir jetzt aber neu, dass es eine exakte
>Repräsentierung für 0.1 gibt. Meines Wissen mündet
>0.1 in einen periodischen Dezimalbruch:

>0.1 = 1/10 ~ 2^-4 + 2^-5 + 2^-8 + 2^-9 + 2^-12 + 2^-13 + ...

>... ein kurzer Google Check scheint das auch zu bestätigen.

Ok, hab mich wohl irgendwie vertan. Obwohl bei 64 Bit ein exaktes 
Ergbnis rauskommt?
Rechenfehler in den Scripten?

http://babbage.cs.qc.edu/IEEE-754/Decimal.html

MFG
Falk

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.