Gleitkommazahl manipulation!



  • union {
      float f;
      uint32_t i;
    } f = { .f = 1.2f };
    f.i &= 0x007fffff;
    


  • Der Standard schreibt kein Modell vor, mit dem Gleitkommazahlen gespeichert werden sollen (im Unterschied zu unsigned-Typen). Deshalb ergibt es keinen Sinn, von den Bits in einer Gleitkomma-Variablen zu reden. Das einzige Bit, das man portabel auslesen kann, ist das man: signbit. 🙂

    Wenn ich recht verstanden hab, was rüdiger da tut, bekommst du so eine Möglichkeit, diese Einschränkung zu umgehen. Trotzdem bleiben die Bits in einer Gleitkomma-Variablen von der Darstellung abhängig, die die CPU oder der Compiler vorgeben. Zum Glück gibt es einen Float-Standard, den viele einhalten:
    http://en.wikipedia.org/wiki/IEEE_754-1985
    🙂



  • Ok, also wenn ich das alles richtig verstehe dann sollte ich anstatt eines Union lieber einen Pointer verwenden denn:

    Bashar schrieb:

    Bei einer union ist nicht definiert, was passiert, wenn man einen Member schreibt und dann einen anderen liest.
    Das solltest du also nicht tun, es sei denn, das ist dir egal. Die Variante mit dem Zeigercast hat dagegen übrigens definiertes Verhalten.

    Wo kann ich z.B.: das definierte Verhalten des Zeigercasts mal nachlesen?

    und weiter:
    Ich kann also nur von Bits reden wenn ich das genauer spezifiziere z.B. 23 bit mantisse und 8 exponent? oder mich auf einen Standard beziehe?

    Aber jetzt schon mal danke... habt mir schon sehr geholfen.

    Gruß muli



  • Bringen wir es auf den punkt, mach es so das es klappt, sobald das so ist, funktioniert es. Geh aber nicht davon aus das es portabel ist, also mit nem anderen compiler oder auf einem anderen ziel system läuft 😉

    muli schrieb:

    Wo kann ich z.B.: das definierte Verhalten des Zeigercasts mal nachlesen?

    schau mal ob du da was findest
    http://www.google.de/search?hl=de&q=n1124.pdf&btnI=Auf+gut+Gl%C3%BCck%21



  • evtl. 6.3.2..



  • Leider muss ich nochmal stören:

    Angenommen ich möchte das Compiler und Plattform unabhängig haben?
    Da schreibt die Spezifikation über unions folgendes:

    A union type describes an overlapping nonempty set of member objects, each of which has an optionally specified name and possibly distinct type.

    Wollen die hier mit dem overlapping sagen das es sich um den gleichen Speicherbereich handelt?

    und weiter 6.2.6.1:

    6. When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values.

    Also wenn ich ein 32 bit float nehem und einen int32 dann sollte dieses padding doch kein problem sein oder?

    When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.

    Das hier ist dann wohl das Problem, oder?
    Das verstehe ich aber nicht so ganz!

    union {
    float f;
    int32 i;
    }u;
    

    Ich dachte in so einem Union würden jetzt u.i und u.f auf den selben speicher verweisen. Also wie kann es denn dann sein das die bytes verschieden sind?
    Oder meint das nur wenn man in so einen union jetzt z.b. einen 32 und einen 64
    integer steckt.
    So um es auch endlich mal auf den Punkt zu bringen 😉
    Wenn ich einen float und ein int32 nehme sollte das doch solange der compiler sich an die von euch genannte IEEE-754 (für single mit auch 32 bit)hält doch ein deterministisches Verhalten auf allen Compilern und Platformen zeigen. D.h. Wenn ich die bits für den u.i verändere das der u.f genau in dieser weise verändert wird.

    Puh ich hoffe daß ich mich irgendwie klar ausgedrückt habe und nicht nur Müll geschrieben habe. Ich lerne aber immer gerne dazu und hoffe ihr könnt mir noch mal helfen.

    Gruß muli



  • nicht der compiler hält sich an IEEE-754 sondern die hardware, und der mach mal klar das sie jetzt plötzlich was anderes verarbeiten soll 😃

    zu 1: denke ja
    zu 2: auch ja porbleme könntest du bekommen bei int und char im union



  • aus der coder hölle schrieb:

    nicht der compiler hält sich an IEEE-754 sondern die hardware

    Stimmt. Oder auch nicht.
    🙂



  • Der Standard schreibt IEEE754 nicht vor. Aber im Anhang F wird es definiert und wenn __STDC_IEC_559__ definiert ist, dann hält sich der Compiler an den IEEE754-Standard. Man kann das ganze also nicht für jeden möglichen ISO C Compiler entwerfen. Aber für ziemlich viele relevante auf relevanten Systemen. Wenn du natürlich obskure C Compiler auf einem µC ohne FP-Einheit nutzt, ist das ganze ein anderes Thema.

    Nimm ein [c]uint32_t[/c] (also unsigned).



  • logische, ne? schrieb:

    @Reudiger
    Lösch das nächste Mal deinen misslungenen Vorschlag wenigstens auch weg. 👎

    Wozu? Damit man die Diskussion nicht mehr versteht? Oder damit rüdiger so unfehlbar dasteht wie der Pabst? Oder damit man langsam die Zensur einschleifen lässt, weil wir alle nach Italien übersiedeln?
    😕



  • µngbd schrieb:

    Oder damit rüdiger so unfehlbar dasteht wie der Pabst?

    Der Mann heisst Papst.


Anmelden zum Antworten