Resource icon

Beispiel für Mantisse Exponent und Vorzeichen einer float-Variablen darstellen

Programmiersprache(n)
c++
Betriebssystem(e)
Linux
Hallo Leute!

Viele von euch werden sich schon mal gefragt haben, wie man die in einer float-Variablen gespeicherte
Fließkomma-Zahl binär darstellt.
Das folgende Beispiel habe ich aus einer von mir erstellten c-Source auf c++ portiert.
Gecodet wurde mit codelite auf SUSE LINUX Tumbleweed mit gcc.
Das hat den Grund, das bei mir die vorhandene codeblocks IDE sich nicht mehr nach einem Update starten lässt.
Nach der Frage nach dem Compiler stürzt codeblocks ab mit der Fehlermeldung

(codeblocks:10557): Gtk-CRITICAL **: 20:22:52.064: IA__gtk_tree_model_iter_nth_child: assertion 'n >= 0' failed
Speicherzugriffsfehler (Speicherabzug geschrieben)
ab. Was soll's, andere Mütter haben auch schöne Töchter.


Daher der Umstieg.

Aber zurück zum wesentlichen.
Zunächst der Header floattest.h:
Code:
#ifndef FLOATTEST_H_INCLUDED
#define FLOATTEST_H_INCLUDED


#include <iostream>
#include <iomanip>
#include <stdlib.h>


union flunch
     {
      float d;
      unsigned char c[4];
     };


//void intzuchar(int zuza, unsigned char (*intteile)[4]);

void showhexadezimal(union flunch a);
void showdezimal(union flunch a);
std::string chartobin(unsigned int letter);
void showbinaer(union flunch a);
void getshowVorkommaanteil(float fzahl);
void getshowNachkommaanteil(float fzahl);
void getfloatparts(union flunch a, short *hoza, int *vzbt, int *manti);
int getvorzeichenbit(unsigned char lbyte);
int getmantisse(unsigned char intteile[]);
short getleftword(unsigned char intteile[]);
void intzuchar(int zuza, unsigned char (*intteile)[4]);
void showergebnisse(int vzbt, short hoza, int manti);


#endif // FLOATTEST_H_INCLUDED
Weiter mit der dazugehörigen floattest.cpp:
Code:
#include "floattest.h"

void showhexadezimal(union flunch a)
{      
int i;
std::cout << "Hexadezimal.......:  ";

for (i=3; i>= 0; i--)
  std::cout << std::hex << (int)a.c[i] <<  " ";
std::cout << std::endl;
}

void showdezimal(union flunch a)
{  
int i;
std::cout << "Dezimal...........:  ";
for (i=3; i>= 0; i--) std::cout << std::dec << (int)a.c[i] << " ";
std::cout << std::endl;
}

std::string chartobin(unsigned int letter)
{
unsigned int slei, dum, testwert;
std::string wort = ""; // Ininitalisert cpp-String mit Null

if ((letter >= 0) || (letter <= 255))
  {
   for (slei = 0; slei <= 7; slei++)
    {
     testwert = 128 >> slei;  // Bit7(128dez) ist auf Char-Nr.0
     dum = letter & testwert;
     if (dum != 0)  wort += '1';
      else          wort += '0';
    }
  }
return wort;
}

void showbinaer(union flunch a)
{      
int i;
std::string binzahl = "";  
std::cout << "Binaer............:  ";

    for (i=3; i>= 0; i--)
     {
      binzahl = chartobin(a.c[i]);
      std::cout << binzahl << " ";
     }
std::cout << std::endl;
}

void getshowVorkommaanteil(float fzahl)
{      
  int i, vk[10],bi[10];

  vk[0] = (int)fzahl / 2;
  bi[0] = (int)fzahl % 2;  
   
   
    std::cout << "\nVorkommaanteil: \n";
    std::cout << std::setw(3) << (int)vk[0] << "=" << (int)bi[0] << std::endl;
    for (i = 0; i <= 8; i++)
    {
     vk[i + 1] = vk[i] / 2;
     bi[i + 1] = vk[i] % 2;
     std::cout << std::setw(3) << (int)vk[i+1] << "=" << (int)bi[i+1] << std::endl;
     if (((vk[i + 1]) == 0) && ((bi[i + 1]) < 2))  break;
    }
}


void getshowNachkommaanteil(float fzahl)
{  
  int i, bink[10];
  float  nkz, nk[10];
   
    //
    // 0,4 * 2 = 0,8 → 0 (Most-Significant-Bit)
    // 0,8 * 2 = 1,6 → 1
    // 0,6 * 2 = 1,2 → 1
    // 0,2 * 2 = 0,4 → 0
    // 0,4 * 2 = 0,8 → 0
    // 0,8 * 2 = 1,6 → 1 (Least-Significant-Bit)
   
    std::cout << "\nNachkommananteil: ";
    nkz = fzahl - (int)fzahl;
    std::cout << "\nNachkommazahl: " << std::setw(9) << nkz << std::endl;
    nk[0]   = nkz * 2;
    bink[0] = 0;
    std::cout << std::setw(9) << std::setprecision(6) << nkz << std::setprecision(6) << "*2=" << nk[0] << "  "  << (int)bink[0]  << std::endl;
    for (i = 0; i <= 9; i++)
    {
     nk[i + 1] = nk[i] * 2;
     if (nk[i + 1] > 1)
     {
      nk[i + 1] -= 1;
      bink[i + 1] = 1;
     }
     else bink[i + 1] = 0;
     std::cout << std::setw(9);
     std::cout << std::left << std::setprecision(6) << nk[i] << std::right << std::setfill(' ') << "*2=" << std::setw(9) << nk[i + 1] << "  "  << (int)bink[i + 1]  << std::endl;
    }
}

void getfloatparts(union flunch a, short *hoza, int *vzbt, int *manti)  
{      
short hochzahl;
   
    hochzahl = getleftword(a.c);
    hochzahl >>= 7;
    hochzahl &= 255;
    *hoza = hochzahl;
   
    *vzbt = getvorzeichenbit(a.c[3]);
    *manti = getmantisse(a.c);
}



int getvorzeichenbit(unsigned char lbyte)
{
int vz = 0;
if ((lbyte & 128) != 0) vz = 1;
  else vz = 0;
return vz;
}

int getmantisse(unsigned char intteile[])
{
int erge = 0;
erge += intteile[2] << 16;
erge += intteile[1] << 8;
erge += intteile[0];
erge &= 8388607;

return erge;
}


short getleftword(unsigned char intteile[])
{
short erge = 0;
erge += intteile[3] << 8;
erge += intteile[2];
return erge;
}

void intzuchar(int zuza, unsigned char (*intteile)[4])
{
union iparts{
int izahl;
unsigned char ichars[4];
} ipts;

ipts.izahl = zuza;
(*intteile)[0] = ipts.ichars[0];
(*intteile)[1] = ipts.ichars[1];
(*intteile)[2] = ipts.ichars[2];
(*intteile)[3] = ipts.ichars[3];
}


void showergebnisse(int vzbt, short hoza, int manti)
{      
int i;
std::string binzahl = "";  
unsigned char intteile[4];
   
binzahl = chartobin(hoza);  
std::cout << "\nVorzeichenbit.....:  " << (int)vzbt;
std::cout << "\nExponent dezimal..:  " << (int)hoza;
std::cout << "\nExponent binaer...:  " << binzahl;
std::cout << "\nMantisse dezimal..:  " << (int)manti;
std::cout << "\nMantisse binaer...:  ";

intzuchar(manti, &intteile);

for (i=2; i>= 0; i--)
  {
   binzahl = chartobin(intteile[i]);
   std::cout << binzahl << " ";
  }
std::cout << std::endl;
}
Nun zur main.cpp:
Code:
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
* main.c
* Copyright (C) 2018 Josef Wismeth <josef@localhost>
*
* floattest1 is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* floattest1 is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Stellt float-Variablen als Fließkomma, hexadezimal, dezmal
* und binaer dar.
*/

#include <iostream>
#include "floattest.h"


int main(void)
  {
    union flunch a;
    int  manti, vzbt;
    float fzahl;
    short hoza;
   
    std::cout << "Bitte eine float-Zahl eingeben: ";
    std::cin >> fzahl;
   
    a.d = fzahl;
   
    std::cout << std::endl << "Dargestellte Zahl:   " << a.d << std::endl;
   
    showhexadezimal(a);
    showdezimal(a);
    showbinaer(a);

    getshowVorkommaanteil(fzahl);
    getshowNachkommaanteil(fzahl);

   
    getfloatparts(a, &hoza, &vzbt, &manti);  
   
    showergebnisse(vzbt, hoza, manti);
   
    a.d = fzahl * -1;
    std::cout << "\n\nDargestellte Zahl:   " << a.d <<std::endl;

    showhexadezimal(a);
    showdezimal(a);
    showbinaer(a);

    getfloatparts(a, &hoza, &vzbt, &manti);  
   
    showergebnisse(vzbt, hoza, manti);
   
    return 0;
  }
Aussehen tut das ganze in der Ausgabe so:
Code:
Bitte eine float-Zahl eingeben: 123.456

Dargestellte Zahl:   123.456
Hexadezimal.......:  42 f6 e9 79
Dezimal...........:  66 246 233 121
Binaer............:  01000010 11110110 11101001 01111001

Vorkommaanteil:
61=1
30=1
15=0
  7=1
  3=1
  1=1
  0=1

Nachkommananteil:
Nachkommazahl:  0.456001
0.456001*2=0.912003  0
0.912003 *2= 0.824005  1
0.824005 *2=  0.64801  1
0.64801  *2= 0.296021  1
0.296021 *2= 0.592041  0
0.592041 *2= 0.184082  1
0.184082 *2= 0.368164  0
0.368164 *2= 0.736328  0
0.736328 *2= 0.472656  1
0.472656 *2= 0.945312  0
0.945312 *2= 0.890625  1

Vorzeichenbit.....:  0
Exponent dezimal..:  133
Exponent binaer...:  10000101
Mantisse dezimal..:  7793017
Mantisse binaer...:  01110110 11101001 01111001

Dargestellte Zahl:   -123.456
Hexadezimal.......:  c2 f6 e9 79
Dezimal...........:  194 246 233 121
Binaer............:  11000010 11110110 11101001 01111001

Vorzeichenbit.....:  1
Exponent dezimal..:  133
Exponent binaer...:  10000101
Mantisse dezimal..:  7793017
Mantisse binaer...:  01110110 11101001 01111001
Freilich gibt es in c++ schon fertig implementierte Medhoden.
Es soll ja nur das Prinzip verdeutlicht werden.

Viel Spaß beim proggen.
rustyoldguy
Autor
rustyoldguy
First release
Last update
Bewertung
0,00 Stern(e) 0 Bewertungen
Oben