Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bitmuster interpretieren

16 views
Skip to first unread message

Robert Hartmann

unread,
Oct 9, 2009, 9:08:55 AM10/9/09
to
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 \n", bitmuster);
printf("Das Bitmuster als Fliesskommazahl: %f \n", bitmuster);
printf("Das Bitmuster als Fliesskommazahl, exp. Schreibweise: %E
\n", bitmuster);
printf("Mit Cast waere Fliesskommazahl: %f \n", (float)bitmuster);
printf("Mit Cast als Fliesskommazahl, exp. Schreibweise: %E \n",
(float)bitmuster);
}
else{
printf("Leider Typgroessen anders als erwartet.\n");
}
return 0;
}


Nach den Antworten zum Threat "printf und Wechselwirkung mit fehlendem
cast" (beginnend mit Message-ID: <4ACDF88F...@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 \n", bitmuster.a);
printf("Das Bitmuster als Fliesskommazahl: %f \n", bitmuster.b);
printf("Das Bitmuster als Fliesskommazahl, exp. Schreibweise: %E
\n", bitmuster.b);
printf("Mit Cast waere Fliesskommazahl: %f \n", (float)bitmuster.a);
printf("Mit Cast als Fliesskommazahl, exp. Schreibweise: %E \n",
(float)bitmuster.a);
}
else{
printf("Leider Typgroessen anders als erwartet.\n");
}
return 0;
}


Gruᅵ Robert

Stefan Reuther

unread,
Oct 9, 2009, 1:34:03 PM10/9/09
to
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
> \n", 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 \n", bitmuster.a);
> printf("Das Bitmuster als Fliesskommazahl: %f \n", bitmuster.b);
> printf("Das Bitmuster als Fliesskommazahl, exp. Schreibweise: %E
> \n", bitmuster.b);
> printf("Mit Cast waere Fliesskommazahl: %f \n", (float)bitmuster.a);
> printf("Mit Cast als Fliesskommazahl, exp. Schreibweise: %E \n",
> (float)bitmuster.a);
> }

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


Stefan

0 new messages