Hallo Besucher, der Thread wurde 1,7k mal aufgerufen und enthält 14 Antworten

letzter Beitrag von Mac Bacon am

wie (dez) 10 in float umwandeln? das ergbnis ist bekannt, nur der binäre rechenweg dort hin nicht...

  • hallo zusammen,
    ich weiss dass (dez) 10 in (mflpt) float sind:
    $hex: $84 20 00 00 00
    %bin: 1000010000100000000000000000000000000000


    und den exponenten kann ich mir noch erklären, aber die mantisse nicht,
    weiss jemand wie das geht?



    die nachkomma (dez) 625 sind %1001110001 - aber die scheinen irgendwie keine rolle zu spielen...


    wie kommt man auf die richtige mantisse?

  • 10000100 00100000 00000000 00000000 00000000

    Bei dieser Darstellung mußt Du daran denken, daß es sich um die gepackte Darstellung handelt. Dabei wird das höchste Bit der Mantisse (, das immer 1 ist,) weggelassen. Die Mantisse müßte also entpackt lauten:
    10000100 0 10100000 00000000 00000000 00000000


    jetzt kann man sehen, daß 1010 der verschobene Binärwert von 10(dez) ist. Um von der Integerzahl zur Fließkommadarstellung zu kommen, muß man also die Bits solange verschieben, bis das das höchste Bit gesetzt ist. Für jedes Verschieben wird der Exponent dabei um 1 erhöht. Dann streicht man das höchste Bit heraus und ersetzt es durch das Vorzeichenbit.
    Ein Sonderfall ist übrigens die Zahl 0. Die hat bekanntlich überhaupt keine gesetzten Bits, so daß die Herumschieberei und das Warten auf ein gesetztes Bit nie aufhören würden. Daher sollte man vorher auf 0 testen.
    Der Fließkommawert für die Zahl 0 ist schlicht 0, d. h. Exponent und Mantisse sind alle 0. Das führt dazu, daß man vor einer Rechenoperation testen sollte, ob ein Operand 0 ist, da man sonst ein falsches Ergebnis erhält.

  • danke euch beiden, soweit war mir das auch klar, aber trotzdem hab ich's nicht verstanden:

    Code
    1. 10000100 0 _0100000 00000000 00000000 00000000
    2. = 10000100 0 10100000 00000000 00000000 00000000
    3. wären 1010 = (dez) 10
    4. exponent: 4 = 4 mal verschieben:
    5. < 10000100 0 10100000 00000000 00000000 00000000
    6. < 10000100 0 0100000 00000000 00000000 00000000
    7. < 10000100 0 100000 00000000 00000000 00000000
    8. < 10000100 0 00000 00000000 00000000 00000000

    oder wie?

  • Da Du die Integerzahl nach Fließkomma mittels Verschiebung nach links umgewandelt hast, mußt Du für die Umwandlung von Fließkomma nach Integer den umgekehrten Weg gehen, also nach rechts verschieben.
    Die Anzahl der Verschiebungen ergibt sich dabei durch Exponent - 127 ($7f), in diesem Falle also 5.


    Edit: Eine kurze Erklärung für die Addition von 127 ($7f) auf den Exponenten (sogenannte Bias) findet sich hier.


    Edit: Nope, stimmt so nicht. Microsoft Basic folgt nicht dem IEEE-Standard. Der Bias ist nicht $7f, sondern $80. Entsprechend ist die Berechnung der Anzahl der Verschiebungen nach rechts anders.

  • der exponent ist in excesscode, aber wie komme ich auf die richtige mantisse?


    ich bin echt nur am rätseln, aber geht's vielleicht so:
    (2^4=) 16 / 10 = 1,60 (dez)
    komma 4 stellen verrücken: 0,160 > 1,60 > 16,0 > 160
    (dez) 160 = %10100000


    10000100 10100000
    ------------^ der wird entfernt (1,x) aber/und genutzt als vorzeichen

  • Ein Sonderfall ist übrigens die Zahl 0. Die hat bekanntlich überhaupt keine gesetzten Bits, so daß die Herumschieberei und das Warten auf ein gesetztes Bit nie aufhören würden. Daher sollte man vorher auf 0 testen.
    Der Fließkommawert für die Zahl 0 ist schlicht 0, d. h. Exponent und Mantisse sind alle 0. Das führt dazu, daß man vor einer Rechenoperation testen sollte, ob ein Operand 0 ist, da man sonst ein falsches Ergebnis erhält.

    In diesem Fall reicht es übrigens nur den Exponent zu beachten, die Mantissen-Bytes sind dann egal. Also Exponent =0 -> Fließkommawart =0, das macht eine entsprechende Abfrage darauf ziemlich einfach. ;)

  • Den Wert vor dem Komma einfach mit dem Verfahren des Vertrauens in eine Binärzahl wandeln. Bei 10 geht das fast intuitiv, in dem man die passenden Zweierpotenzen 8 (binär 1000) und 2 (binär 10) zerlegt, was dann 1010 ergibt. Z.B. kann man das auch so machen, in dem man sich für eine gerade Zahl eine 0 für eine ungerade eine 1 notiert, dann durch 2 ganzzahlig dividieren und wieder ungerade/gerade als Bit notiert (links davon anschreibt).
    10 -> 0
    5 -> 1
    2 -> 0
    1 -> 1
    also 1010 in 4 Schritten -> Exponent 4 + Exzess.
    Bei Nachkommastellen geht's ähnlich, nur halt mit Mulitiplikation von 2, wenn
    0,375 -> 0
    0,750 -> 0
    1,5 -> 1 (bleibt 0,5)
    1,0 -> 1
    ergibt binär 0,011
    Beim Nachkommateil können auch Bitfolgen entstehen die nie auf 1,0 aufgehen und daher abgebrochen werden müssen, wenn die Mantisse "voll" ist. Das sind nicht exakt darstellbare Dezimalzahlen, wie z.B. 0,1 welche zu einer periodischen unendlichen Binärziffernfolge führt. Auch einer Gründe, warum Fließkommazahlen für das Nachkommastellen problematisch sind und im Finanzwesen auf BCD-Darstellung ausgewichen wird, um so etwas wie 0,1 exakt darstellen, erfassen und damit exakt rechnen zu können.

  • der exponent ist in excesscode,

    Ja, genau: "Im IEEE-754-Standard zur Darstellung von Gleitkommazahlen wird der Exponent in einer Exzesscode-ähnlichen Form kodiert." Wird auch vom Basic benutzt, jedoch in einer zum IEEE-Standard abgewandelten Form, die mich ein wenig verwirrt hat. :hae:

    Evtl. hilft dies?

    Mac Bacon: Eine Frage hierzu: In dem von Dir verlinkten Programmtext steht, daß der Bias $80 beträgt. Im Basic-Rom findet sich nun bei $baf9 der Wert 84 20 00 00 00 wie von e2020 genannt. Im IEEE-Format ergibt sich bei einem Bias von $7f jedoch 82 20 00 00, also ein um 2 verringerter Exponent im Vergleich zum Basic. Sollte daher bei einem Bias von $80 der Wert nicht 83 20 00 00 sein? Wie kommt man denoch auf die $84? :gruebel Liegt es vielleicht daran, daß beim Exponenten das im gepackten Memory-Format weggelassene 1-Bit nicht mitgezählt wird? Oder wie? Oder was?

    wie kommt man auf die richtige mantisse

    Von Integer ==> Float
    Zahl: %00000000 00001010 Startexponent $90
    Verschiebe die Zahl nach links (*2), bis das höchste Bit gesetzt ist und erniedrige (nicht erhöhen) pro Verschiebung den Exponenten:
    Zahl: %00000000 00010100 Exponent: $8f
    Zahl: %00000000 00101000 Exponent: $8e
    ...
    Zahl: %10100000 00000000 Exponent: $84


    Von Float ==> Integer
    Zahl: %10100000 00000000 Exponent $84
    Verschiebe die Zahl nach rechts (/2) und erhöhe dabei den Exponenten, bis er $90 wird.
    Zahl: %01010000 00000000 Exponent $85
    Zahl: %00101000 00000000 Exponent $86
    ...
    Zahl: %00000000 00001010 Exponent $90

  • In dem von Dir verlinkten Programmtext steht, daß der Bias $80 beträgt. Im Basic-Rom findet sich nun bei $baf9 der Wert 84 20 00 00 00 wie von e2020 genannt. Im IEEE-Format ergibt sich bei einem Bias von $7f jedoch 82 20 00 00, also ein um 2 verringerter Exponent im Vergleich zum Basic. Sollte daher bei einem Bias von $80 der Wert nicht 83 20 00 00 sein? Wie kommt man denoch auf die $84?

    Puh, gute Frage. Als ich das Makro geschrieben habe, ging es mir hauptsächlich darum, dass es exakt die gleiche Bitfolge generiert wie der Basic-Interpreter (meines Wissens tut es das). Dass im Kommentar der Bias $80 erwähnt wird, liegt daran, dass der dezimale Wert 0,5 als $80 00 00 00 00 abgelegt wird. Warum nun 0,5 und nicht 1?
    Letzlich dürfte es darauf hinaus laufen, wie man die Mantisse definiert: In der "wissenschaftlichen Darstellung" von z.B. Taschenrechner-Anzeigen soll die Mantisse genau eine Dezimalstelle ungleich Null vor dem Komma haben - wie z.B. "2,9341 * 10^6".
    Bei binärer Darstellung im Rechner finde ich es aber viel intuitiver, wenn diese erste Nicht-Null hinter dem Komma steht, denn dann hat die Mantisse immer einen Wert zwischen 0 und 1. Stünde die erste Eins vor dem Komma, hat die Mantisse einen Wert zwischen 1 und 2, und dieses Intervall mutet dagegen fast schon beliebig an.


    Der langen Rede kurzer Sinn: Nach IEEE-Sprech mag der Bias falsch sein, aber im Interpreter-Kontext scheint er mir sinnvoll.

  • Genau, die Interpreter-Darstellung der Floats definiert für den Exzess $80 die Wertigkeit 0,5 für das führende Bit. Da das führende Bit von 10 die Wertigkeit 8 hat, sind das 2^3 und bezogen auf 2^(-1) ergibt das dann einen Exponentendifferenz von 4, also einen Exponentwert $80 + 4. Exzess heißt ja allgemein nur ein Versatz ... auch wenn von IEEE ein Standard für eine Darstellung gegeben ist, so ist das eben auch nur eine von vielen Möglichkeiten. ;)

  • Vielen Dank für die ausführliche Erklärung!
    Nach dem ollen IEEE-Standard wäre das dann ein Bias von $81, nach dem Mac Bacon/C64-Standard aber $80. ^^ Dann weiß ich ja bescheid, falls ich wider Erwarten mal in Verlegenheit kommen sollte, Fließkommazahlen im Basic-Format zu erzeugen.

  • Nach dem ollen IEEE-Standard wäre das dann ein Bias von $81, nach dem Mac Bacon/C64-Standard aber $80. ^^

    Ich weiß zwar nicht mehr, wo ich "exponent has a bias of 128" her habe, aber auf meinem Mist gewachsen ist das nicht. ;)