Kommazahl in dezimal umwandeln

Gast #1625952
Lesenswert?

Hallo  Max
>ich bin gerad vor einem rätzel. Wie kann ich die Kommazahl bsp. 0,3 in
>Binär und dann in Dezimal ausgeben?
Das sind wenige Angaben was Du genauer vorhast. Nehme es mal 10 dann ist 
die "0" und das Komma weg(einfach Streichen). Wenn Du es Anzeigen willst 
setzt Du die "0" und das Komma einfach wieder davor.
Gast #1625974
Lesenswert?

Hallo MaroT,

also genauer möchte ich nach IEEE754 vorgehen. Ich hab einiges vom Code 
geschrieben.
Hasst recht hab es nicht deutlich geschrieben gehabt.
Also ich hab eine Zahl 32,3 und diese möchte ich nach IEEE754 in 
Hexadezimal zahl umwandeln. Ich bin so weit gekommen, dass ich die 
Vordere zahl konvertiert habe. Es fehlt mir nur nachkommazahl. Also in 
prinzip:

0,3 * 2 = 0,6->0
0,6 * 2 = 1,2->1
0,2 * 2 = 0,4->0
0,4 * 2 = 0,8->0
0,8 * 2 = 1,6->1

bin 01001.... und dann in Hex

Sorry einbisschen programmierkenntnisse fehlen mir :(
#1625992
Lesenswert?

Max schrieb:
> Hallo MaroT,
>
> also genauer möchte ich nach IEEE754 vorgehen. Ich hab einiges vom Code
> geschrieben.
> Hasst recht hab es nicht deutlich geschrieben gehabt.
> Also ich hab eine Zahl 32,3 und diese möchte ich nach IEEE754 in
> Hexadezimal zahl umwandeln.

Du wandelst überhaupt nichts nach 'Hexadezimal'. Hexadezimal ist nur 
eine Schreibweise. Im Rechner ist alles einfach nur 'eine Zahl'. Diese 
Zahl kann man in verschiedenen Repräsentierungen wiedergeben, binär, 
dezimal, hex, aber grundsätzlich ist es einfach nur eine Zahl 
(eigentlich nicht mal das, im eigentlichen Sinne ist es nur ein 
Bitmuster)

> Ich bin so weit gekommen, dass ich die
> Vordere zahl konvertiert habe.

Und wie hast du das gemacht?
Und in welcher Sprache?

> Es fehlt mir nur nachkommazahl. Also in
> prinzip:
>
> 0,3 * 2 = 0,6->0
> 0,6 * 2 = 1,2->1
> 0,2 * 2 = 0,4->0
> 0,4 * 2 = 0,8->0
> 0,8 * 2 = 1,6->1


was mich ein wenig stutzig macht, ist deine konsequente Verwendung eines 
',' für den Dezimalpunkt. In der Programmierung ist ein Dezimalpunkt 
immer ein '.'.

Dies deshalb, weil
* Programmiersprachen aus dem amerikanischen Sprachraum kommen und dort
  ein . üblich ist
* Ein Komma als Aufzählungszeichen benutzt wird (zb um Argumente an
  Funktionen zu trennen)
Gast #1626014
Lesenswert?

Möchtest du eine Gleitpunktzahl einfach nur binär ausgeben?
1
typdef union {
2
    float f_val;
3
    uint32_t i_val;
4
} ftou_t;
5

6
ftou_t foo;
7
foo.f_val = 0.3;
8

9
for(i = 31; i >= 0; --i) {
10
    putc((foo.i_val)&(1<<i) ? '1' : '0');
11
}

Dabei beachten das nicht auf allen Plattformen (z.B. AVR) auch ein 
Double vorhanden ist. Beim AVR ist ein Double ebenfalls nur 32 Bit lang.
Gast #1626015
Lesenswert?

Max,

schau Dir die konvertierungs routinen an von den gcc compiler.
Der tut genau das, ohne dabei den "float" oder "double" zu verwenden.
von asc->single float, asc->double float etc etc..

Ach ja... suche dir ein alte compiler (pre gcc 3.0) da ist es 
verstaendlicher und der per cpu optimierungs blabla ist nicht dabei. vor 
jahren hatte ich das selber problem, habe damals die konvertierungs 
routine extrahiert und verwendet. (die datei heisst gcc/real.c )

gruss roman
Gast #1626117
Lesenswert?

Hallo  Max
>ich bin gerad vor einem rätzel. Wie kann ich die Kommazahl bsp. 0,3 in
>Binär und dann in Dezimal ausgeben?
>Soweit ich weiss Gleitkomma hat er nicht.
Ist doch schon die halbe Antwort. Was nicht geht geht halt nicht.
Kannst Du es nicht so machen wie ich oben schon geschrieben habe?
Karl heinz Buchegger schrieb
>... im eigentlichen Sinne ist es nur ein Bitmuster)
Du willst doch das der µC etwas rechnet, ob da ein Komma ist oder nicht 
interessiert doch keinen. Mußt ihm nur die "Zahlen" so geben das er es 
richtig macht(wenn z.B "+1" dann mußt Du wenn es eine Kommastelle war 
halt mit 10 addieren). Wenn Du die Zahlen wieder nach Dezimal wandelst 
machst Du einfach das Komma an der richtigen Stelle wieder rein. Du 
kannst damit deinem µC viel Arbeit abnehmen.
>auch in Hexadezimalzahl
Gehe mal davon aus, das es nur Bit giebt.
Hexadezimalzahl schreibt man nur das es schöner aussieht wegen der 
vielen Nullen und Einsen. Ein Prozessor weiß nicht was Du von ihm 
willst.
henky schrieb
>Weißt du wie eine Fließkommazahl binär aussieht?
oder Hexadezimalzahl?
Das einzige was möglich ist jedes Byte mit ASCII anzuzeigen.
Gast #1626124
Lesenswert?

MarioT schrieb:
>>Weißt du wie eine Fließkommazahl binär aussieht?
> oder Hexadezimalzahl?
> Das einzige was möglich ist jedes Byte mit ASCII anzuzeigen.
Er kann ja auch die Mantisse und Co. rauspulen und und angeben... wenn 
sein Lehrer das so möchte. ;-)
#1626170
Lesenswert?

Die wichtigste Frage ist für mich:
In welcher Sprache soll das ganze abgehandelt werden?

Wenn es C ist UND ein Compiler zur Verfügung steht, der bereits IEEE754 
macht, dann ist die Aufgabe ziemlich trivial. Wenn man aber mehr oder 
weniger, die Floating Point Library, die der Compiler mitbringt, nicht 
benutzen kann, dann wirds aufwändig. Dann muss man erst mal damit 
anfangen, sich die Basisfunktionen in IEEE754-Floating Point für 
Addition, Multiplikation und Division zu schreiben. Hat man die erst mal 
fertig, wirds wieder einfacher. Man kann dann zwar nicht mehr direkt 
schreiben

   result = 10 * result + nextDigit;

sondern muss das durch entsprechende Aufrufe in diese Basislibrary 
ersetzen. Das Prinzip bleibt allerdings nach wie vor dasselbe.

Vorkommateil:

   result = 10 * result + nextDigit;

Nachkommateil:

   result = result + nextDigit * stelle;
   stelle /= 10;

Die einzigen Floating Point Konstanten, deren Byte-Repräsentierung man 
kennen muss, sind 1 und 10
Gast #1626188
Lesenswert?

Karl heinz Buchegger schrieb:
> Die wichtigste Frage ist für mich:
> In welcher Sprache soll das ganze abgehandelt werden?
Das hat Max im zweiten Post verraten. ;-)
Max schrieb:
> Natürlich in C!

Karl heinz Buchegger schrieb:
> Wenn es C ist UND ein Compiler zur Verfügung steht, der bereits IEEE754
> macht, dann ist die Aufgabe ziemlich trivial. Wenn man aber mehr oder
> weniger, die Floating Point Library, die der Compiler mitbringt, nicht
> benutzen kann, dann wirds aufwändig.
Das hat Max noch nicht verraten.
Ansonsten, keine Ahnung von so was, ich glaube dir einfach mal. ;-)
#1626198
Lesenswert?

henky schrieb:
> Karl heinz Buchegger schrieb:
>> Die wichtigste Frage ist für mich:
>> In welcher Sprache soll das ganze abgehandelt werden?
> Das hat Max im zweiten Post verraten. ;-)
> Max schrieb:
>> Natürlich in C!

Mein Fehler. Hab ich überlesen.

> Karl heinz Buchegger schrieb:
>> Wenn es C ist UND ein Compiler zur Verfügung steht, der bereits IEEE754
>> macht, dann ist die Aufgabe ziemlich trivial. Wenn man aber mehr oder
>> weniger, die Floating Point Library, die der Compiler mitbringt, nicht
>> benutzen kann, dann wirds aufwändig.
> Das hat Max noch nicht verraten.
> Ansonsten, keine Ahnung von so was, ich glaube dir einfach mal. ;-)

Ich dachte auch immer, dass das wahsinnig aufwändig sei und bin vor 
dieser Aufgabe gestanden, wie der Ochs vorm Tor.
Bis ich dann den Code eines professionellen Pascal-Compilers in die 
Finger bekam. Natürlich suchte ich die betreffende Stelle und machte 
mich darauf gefasst, da auf eine Byteorgie zu stossen.

Aber Pustekuchen: Das war eine ganz normale Zahleneinleseroutine, so wie 
man sie macht, wenn man von einer Seriellen einen ASCII-Text 
hereinbekommt. Und da ist es mir dann gedämmert. Die Byte-Orgie braucht 
nicht im Pascal-Quelltext stehen, weil sie der compilierende Pascal 
Compiler schon beherrscht. Damit hat man dann das Henne-Ei Problem. Im 
allerersten Compiler muss man die normale Schreibweise gegen eine mit 
direkten Library Aufrufen ersetzen und die vorkommenden Konstanten (sind 
nur 1 und 10) einmal händisch in ihre Floating-Point Byte Form 
übersetzen, sofern es keine int->float Funktion gibt). Sobald aber der 
Urcompiler soweit steht, dass er das alles übersetzen kann, wird das 
dann im Zuge des Bootstrap-Prozesses durch den endgültigen, einfachen 
Code ersetzt.

Daher die Fragestellung: Worauf kann man aufbauen? Steht ein C-Compiler 
zur Verfügung, dessen Floating Point Behandlung mitbenutzt werden darf 
oder nicht?

Wenn ja, dann zb so (ohen Behandlung von Exponenten und Vorzeichen)
1
double readFloat( const char* text )
2
{
3
  double result = 0.0;
4
  double fraction = 1.0;
5

6
  while( *text &&
7
         *text != '.' &&
8
         ( *text >= '0' && *text <= '9' )
9
    result = 10 * result + ( *text - '0' );
10

11
  if( *text != '.' )
12
    return result;
13

14
  while( *text &&
15
         *text >= '0' && *text <= '9' ) {
16
    fraction /= 10.0;
17
    result = result + ( *text - '0' ) * fraction;
18
  }
19

20
  return result;
21
}

Eine andere Möglichkeit wäre es, den Nachkommaanteil ebefalls zunächst 
als normale ganze Zahl einzulesen und dabei die Anzahl der Stellen 
mitzuzählen, damit die Division zur Verschiebung in den Nachkommaanteil 
erst ganz zum Schluss gemacht werden kann.
Gast #1626546
Lesenswert?

Hallo Leute,

Danke für eure hilfe!
Ich hab es ma so gemacht und es funktioniert wunderbar :D

tobi schrieb:
> typdef union {
>
>     float f_val;
>
>     uint32_t i_val;
>
> } ftou_t;
>
>
>
> ftou_t foo;
>
> foo.f_val = 0.3;
>
>
>
> for(i = 31; i >= 0; --i) {
>
>     putc((foo.i_val)&(1<<i) ? '1' : '0');
>
> }

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