Interne Zahlendarstellung Typ float



  • Hallo Leute!

    Irgendwer hat im Internet dieses kleine prog reingestellt, das die
    Zahlendarstellung von Fließkommazahlen typ float ermöglicht.
    Ich habe nur eine kleine Funktion dazugestellt, um das ganze mal
    auch binär zu sehen.
    Einen Schönheitspreis will ich dafür nicht gewinnen, zum
    experimentieren reicht es aber:

    /*
      Stellt float-Variablen als Fließkomma, hexadezimal, dezimal
      und binaer dar.
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    void chartobin(unsigned int letter, char wort[])
    {
    unsigned int slei, dum, testwert;
     if ((letter < 0) || (letter > 255)) goto finito;
    
     /* Ininitalisert die 8 Binärstellen mit Null */
     for (slei = 0; slei <= 11; slei++)
      wort[8] = '\0';
    
     for (slei = 0; slei <= 7; slei++)
      {
       testwert = 128 >> slei;  /* Bit7(128dez) ist auf Char-Nr.0 */
       dum = letter & testwert;
       if (dum != 0)  wort[slei] = '1';
        else          wort[slei] = '0';
      }
    finito:    ;
    }
    
    int main(void)
      {
        int i;
        union
         {
          float d;
          unsigned char c[4];
         } a;
    
         char binzahl[20];
        a.d = 0.001273;
        printf("Dargestellte Zahl: %f\n", a.d);
        printf("Hexadezimal:\n");
    
        for (i=3; i>= 0; i--)
         printf("%02x ", a.c[i]);
         printf("\n\nDezimal:\n");
    
        for (i=3; i>= 0; i--)
         printf("%02d ", a.c[i]);
    
         printf("\n\nBinaer:\n");
    
        for (i=3; i>= 0; i--)
         {
          chartobin(a.c[i], binzahl);
          printf("%s ", binzahl);
         }
    
        a.d = -0.001273;
        printf("\n\nDargestellte Zahl: %f\n", a.d);
        printf("Hexadezimal:\n");
    
        for (i=3; i>= 0; i--)
         printf("%02x ", a.c[i]);
         printf("\n\nDezimal:\n");
    
        for (i=3; i>= 0; i--)
         printf("%02d ", a.c[i]);
    
         printf("\n\nBinaer:\n");
    
        for (i=3; i>= 0; i--)
         {
          chartobin(a.c[i], binzahl);
          printf("%s ", binzahl);
         }
        return 0;
      }
    

    Ausgabe wie folgt:

    Dargestellte Zahl: 0.001273
    Hexadezimal:
    3a a6 da cb 
    
    Dezimal:
    58 166 218 203 
    
    Binaer:
    00111010 10100110 11011010 11001011 
    
    Dargestellte Zahl: -0.001273
    Hexadezimal:
    ba a6 da cb 
    
    Dezimal:
    186 166 218 203 
    
    Binaer:
    10111010 10100110 11011010 11001011
    


  • Ich nehme da gerne http://www.h-schmidt.net/FloatConverter/IEEE754.html

    gcc schrieb:

    C:\Users\..\main.c|12|warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]|

    (Das mit dem goto ist doch Vorsatz)



  • Hallo DrikB!

    Sorry für das goto.

    Mea maxima culpa!

    void chartobin(unsigned int letter, char wort[])
    {
    unsigned int slei, dum, testwert;
     if ((letter >= 0) && (letter <= 255))
      {
     /* Ininitalisert die 8 Binärstellen mit Null */
     for (slei = 0; slei <= 11; slei++)
      wort[8] = '\0';
    
     for (slei = 0; slei <= 7; slei++)
      {
       testwert = 128 >> slei;  /* Bit7(128dez) ist auf Char-Nr.0 */
       dum = letter & testwert;
       if (dum != 0)  wort[slei] = '1';
        else          wort[slei] = '0';
      }
     }
    }
    

    Besser so?
    Die Funktion habe ich mir geschrieben, wei sie keine Vornullenunterdrückung hat.
    Ist noch von meiner alten Zeit hängen geblieben.
    Danke übrigens für die Seite. Ich werde sie mir merken. Ein Rätzel ist
    es mir übrignes, wie man die Zahl 2546379 in 1.3035520315170288
    umwandelt. Ebenso, wie der Exponent 2^(-10) aus der Zahl 117 gebildet wird.
    Wenigstens zeigt die Seite, das ich die Bytes richtig
    ausgelesen habe.

    Da ist noch eine Frage DrikB:
    Wenn ich eine float-Variable in einer Datei abspeichern will, im
    IEEE 754-Format, wäre dann Reihenfolge des kleinen Progs richtig, also
    zuerst das Byte mit dem Vorzeichenbit, also
    zuerst 3a dann a6, da und schließlich cb?

    Nun das geringfügig überarbeitete prog:

    /*
      Stellt float-Variablen als Fließkomma, hexadezimal, dezmal
      und binaer dar.
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    void chartobin(unsigned int letter, char wort[])
    {
    unsigned int slei, dum, testwert;
     if ((letter >= 0) && (letter <= 255))
      {
     /* Ininitalisert die 8 Binärstellen mit Null */
     for (slei = 0; slei <= 11; slei++)
      wort[8] = '\0';
    
     for (slei = 0; slei <= 7; slei++)
      {
       testwert = 128 >> slei;  /* Bit7(128dez) ist auf Char-Nr.0 */
       dum = letter & testwert;
       if (dum != 0)  wort[slei] = '1';
        else          wort[slei] = '0';
      }
     }
    }
    
    int getvorzeichenbit(unsigned char lbyte)
    {
     int vz = 0;
     if ((lbyte & 128) != 0) vz = 1;
      else vz = 0;
     return vz;
    }
    
    short getleftword(unsigned char intteile[])
    {
     short erge = 0;
     erge += intteile[3] << 8;
     erge += intteile[2];
    return erge;
    }
    
    int getmantisse(unsigned char intteile[])
    {
     int erge = 0;
     erge += intteile[2] << 16;
     erge += intteile[1] << 8;
     erge += intteile[0];
     erge &= 8388607;
    
    return erge;
    }
    
    void intzuchar(int zuza, unsigned char (*intteile)[])
    {
     (*intteile)[0] = zuza & 255;
     (*intteile)[1] = (zuza & (255 << 8)) >> 8;
     (*intteile)[2] = (zuza & (255 << 16)) >> 16;
     (*intteile)[3] = (zuza & (255 << 24)) >> 24;
    }
    
    int main(void)
      {
        int i, manti, vzbt;
        float fzahl;
        short hoza;
        union
         {
          float d;
          unsigned char c[4];
         } a;
         char binzahl[20];
         unsigned char intteile[4];
    
        printf("Bitte eine float-Zahl eingeben: ");
        scanf("%f", &fzahl);
        a.d = fzahl;
        printf("Dargestellte Zahl: %f\n", a.d);
        printf("Hexadezimal......: ");
    
        for (i=3; i>= 0; i--)
         printf("%02x ", a.c[i]);
        printf("\n\nDezimal..........: ");
    
        for (i=3; i>= 0; i--)
         printf("%02d ", a.c[i]);
    
         printf("\n\nBinaer...........: ");
    
        for (i=3; i>= 0; i--)
         {
          chartobin(a.c[i], binzahl);
          printf("%s ", binzahl);
         }
        hoza = getleftword(a.c);
        hoza >>= 7;
    
        hoza &= 255;
        vzbt = getvorzeichenbit(a.c[3]);
        printf("\nVorzeichenbit...:  %d", vzbt);
        printf("\nExponent dezimal:  %d", hoza);
        manti = getmantisse(a.c);
        printf("\nMantisse dezimal:  %d", manti);
        chartobin(hoza,binzahl);
        printf("\n\nExponent binaer  : %s", binzahl);
        printf("\nMantisse binaer  : ");
        intzuchar(manti, &intteile);
    
         for (i=2; i>= 0; i--)
         {
          chartobin(intteile[i], binzahl);
          printf("%s ", binzahl);
         }
    
        a.d = fzahl * -1;
        printf("\nDargestellte Zahl: %f\n", a.d);
        printf("Hexadezimal......: ");
    
        for (i=3; i>= 0; i--)
         printf("%02x ", a.c[i]);
        printf("\nDezimal..........: ");
    
        for (i=3; i>= 0; i--)
         printf("%02d ", a.c[i]);
    
         printf("\n\nBinaer...........: ");
    
        for (i=3; i>= 0; i--)
         {
          chartobin(a.c[i], binzahl);
          printf("%s ", binzahl);
         }
        hoza = getleftword(a.c);
        hoza >>= 7;
    
        vzbt = getvorzeichenbit(a.c[3]);
        printf("\nVorzeichenbit...:  %d", vzbt);
        hoza &= 255;
        printf("\nExponent dezimal:  %d", hoza);
        manti = getmantisse(a.c);
        printf("\nMantisse dezimal:  %d", manti);
        chartobin(hoza,binzahl);
        printf("\n\nExponent binaer  : %s", binzahl);
        printf("\nMantisse binaer  : ");
        intzuchar(manti, &intteile);
    
         for (i=2; i>= 0; i--)
         {
          chartobin(intteile[i], binzahl);
          printf("%s ", binzahl);
         }
    
        return 0;
      }
    

    Für die "Null" die zuviel angezeigt wird beim höchstwertigen Byte der
    Mantisse möchte ich mich entschuldigen. aber ich bin zu faul, um die
    Funktion chartobin extra nur für dieses Byte umzuschreiben.



  • rustyoldguy schrieb:

    unsigned int letter;
    ...
    if ((letter >= 0) || (letter <= 255))
    

    Diese Bedingung ist immer wahr.
    Und das meldet dir auch der Compiler, wenn du die (richtigen) Warnungen aktivierst.
    ^(Weiter habe ich nicht geschaut)^

    Die Reihenfolge hängt von der Endianess des Systems ab.



  • Und was lernt uns das? 😕



  • Stimmt, riesen Schlamperei von mir, wurde bereits korrigiert.
    Eine Seite mit Berechnungsbeispielen habe ich auch gefunden.
    Eine weitere Betrachtung meinerseits erübrigt sich.
    Das Rad muß nicht noch einmal erfunden werden.


Log in to reply