Bitmuster interpretieren

09/10/2009 - 15:08 von Robert Hartmann | Report spam
Hallo zusammen,

bibt es die Möglichkeit standardkonform und damit
mehr oder weniger compilerübergreifend ein und das Selbe
Bitmuster der Lànge 1Byte sowohl als
char, short int, unsigned short int, long int, unsigned long int,
aber auch als float und double interpretiert auszugeben?

Wie sieht es bei folgender Einschrànkung aus:
Das Bitmuster eines long int (mit 4 Bytes) soll als
Bitmuster eines float (mit 4 Bytes) interpretiert werden.

Ich persönlich hàtte es primitiv so gemacht:

#include <stdio.h>
#include <limits.h>

int main(){

if ((sizeof(float)==4)&&(sizeof(long int) == sizeof(float)))
{
/*Führende Nullen im Bitmuster mal weggelassen: 1111001*/
long int bitmuster = 0xF1;
printf("Das Bitmuster ganzahlig mit Vorzeichen: %ld ", bitmuster);
printf("Das Bitmuster als Fliesskommazahl: %f ", bitmuster);
printf("Das Bitmuster als Fliesskommazahl, exp. Schreibweise: %E
", bitmuster);
printf("Mit Cast waere Fliesskommazahl: %f ", (float)bitmuster);
printf("Mit Cast als Fliesskommazahl, exp. Schreibweise: %E ",
(float)bitmuster);
}
else{
printf("Leider Typgroessen anders als erwartet.");
}
return 0;
}


Nach den Antworten zum Threat "printf und Wechselwirkung mit fehlendem
cast" (beginnend mit Message-ID: <4ACDF88F.9010405@gmx.net> ) ist
die obige primitive Lösung nicht immer durchführbar, insbesondere dann
nicht, wenn mit mehreren Variablen nacheinander dasselbe Spiel gemacht wird.

Natürlich könnte ich eine union anlegen,
so dass sich ein long int und ein float (bei gleicher Größe)
einen Speicherbereich teilen. Aber dann muss ich bei der
printf-Anweisung auch zwischen den Namen wàhlen.

Was für eine erste Übung mit Leuten, die noch nie
Programmiert haben, evtl deutlich über dem Level ist.

Die Lösung mit Union sàhe bei mir so aus:

#include <stdio.h>
#include <limits.h>

int main(){

if ((sizeof(float)==4)&&(sizeof(long int) == sizeof(float)))
{
union {
long int a;
float b;
} bitmuster;

/*Führende Nullen im Bitmuster mal weggelassen: 1111001*/
bitmuster.a = 0xF1;
printf("Das Bitmuster ganzahlig mit Vorzeichen: %ld ", bitmuster.a);
printf("Das Bitmuster als Fliesskommazahl: %f ", bitmuster.b);
printf("Das Bitmuster als Fliesskommazahl, exp. Schreibweise: %E
", bitmuster.b);
printf("Mit Cast waere Fliesskommazahl: %f ", (float)bitmuster.a);
printf("Mit Cast als Fliesskommazahl, exp. Schreibweise: %E ",
(float)bitmuster.a);
}
else{
printf("Leider Typgroessen anders als erwartet.");
}
return 0;
}


Gruß Robert
 

Lesen sie die antworten

#1 Stefan Reuther
09/10/2009 - 19:34 | Warnen spam
Robert Hartmann wrote:
Wie sieht es bei folgender Einschrànkung aus:
Das Bitmuster eines long int (mit 4 Bytes) soll als
Bitmuster eines float (mit 4 Bytes) interpretiert werden.

Ich persönlich hàtte es primitiv so gemacht:


[...]
long int bitmuster = 0xF1;
printf("Das Bitmuster als Fliesskommazahl, exp. Schreibweise: %E
", bitmuster);



Das klappt schon deswegen nicht, weil %E einen double erwartet, der
üblicherweise mehr Speicher braucht als ein long int.

Natürlich könnte ich eine union anlegen,
so dass sich ein long int und ein float (bei gleicher Größe)
einen Speicherbereich teilen. Aber dann muss ich bei der
printf-Anweisung auch zwischen den Namen wàhlen.



Das ist aber IMHO die einzige Methode, die halbwegs taugt. Neben der
Methode, mehrere Variablen anzulegen und memcpy zu verwenden. Bei fast
allem anderen kommst du dank der Aliasingregeln aus 6.5p7 zu
undefiniertem Verhalten.

Was für eine erste Übung mit Leuten, die noch nie
Programmiert haben, evtl deutlich über dem Level ist.



Was interessiert einen Anfànger, wie ein double im Speicher aussieht?
Das interessiert mich ja selbst als Profi nur alle Jubeljahre mal.

if ((sizeof(float)==4)&&(sizeof(long int) == sizeof(float)))



Ich hàtte ja einfach sizeof(float)==sizeof(long) geschrieben.

{
union {
long int a;
float b;
} bitmuster;

/*Führende Nullen im Bitmuster mal weggelassen: 1111001*/
bitmuster.a = 0xF1;
printf("Das Bitmuster ganzahlig mit Vorzeichen: %ld ", bitmuster.a);
printf("Das Bitmuster als Fliesskommazahl: %f ", bitmuster.b);
printf("Das Bitmuster als Fliesskommazahl, exp. Schreibweise: %E
", bitmuster.b);
printf("Mit Cast waere Fliesskommazahl: %f ", (float)bitmuster.a);
printf("Mit Cast als Fliesskommazahl, exp. Schreibweise: %E ",
(float)bitmuster.a);
}



Ansonsten würde ich das ungefàhr so machen. Nur der Cast ist hinreichend
überflüssig.


Stefan

Ähnliche fragen