Bitfolge ausgeben

Bitfolge ausgeben

am 20.03.2006 15:02:44 von Herbert Voss

#!/usr/bin/perl -w

sub binMuster{
my ($zahl) = @_;
my $binZahl = "";
for ($j=0; $j<32; $j++) {
if ($zahl & 1) { $binZahl = "1".$binZahl; } else { $binZahl =
"0".$binZahl; }
$zahl >>= 1;
}
return $binZahl;
}

print binMuster(0.1)."\n";
print binMuster(10)."\n";


warum funktioniert das Ganze nicht für Fließkommazahlen?

Herbert

Re: Bitfolge ausgeben

am 20.03.2006 15:44:10 von Christian Lackas

* Herbert Voss [2006-03-20]:

Hallo Herbert,

> print binMuster(0.1)."\n";
> print binMuster(10)."\n";
> warum funktioniert das Ganze nicht für Fließkommazahlen?

weil der Operator '&' nur für 'Integer Arithmetic' definiert ist (siehe
auch perldoc perlop). Fließkommazahlen werden idR im IEEE-Format
gespeichert:

http://www.math.byu.edu/~schow/work/IEEEFloatingPoint.htm

Da macht ein bitweises Verknüpfen keinen Sinn.

Gruß
Christian


--
Viele schimpfen auf die Behörden -
dabei haben die doch gar nichts getan.
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: Bitfolge ausgeben

am 20.03.2006 15:56:00 von Wolf Behrenhoff

Herbert Voss schrieb:
> if ($zahl & 1) { $binZahl = "1".$binZahl; } else { $binZahl =
> "0".$binZahl; }
> warum funktioniert das Ganze nicht für Fließkommazahlen?

Weil & mit Integer-Zahlen arbeitet und daher Fließkommazahlen vor
Anwendung des Operators & in Integer gewandelt werden.

Mit pack/unpack geht sowas aber, zum Beispiel
perl -e "print unpack('b64', pack('d', 0.1))"

Wolf

Re: Bitfolge ausgeben

am 20.03.2006 16:41:17 von Herbert Voss

Wolf Behrenhoff wrote:
> Herbert Voss schrieb:
>
>> if ($zahl & 1) { $binZahl = "1".$binZahl; } else { $binZahl =
>>"0".$binZahl; }
>>warum funktioniert das Ganze nicht für Fließkommazahlen?
>
>
> Weil & mit Integer-Zahlen arbeitet und daher Fließkommazahlen vor
> Anwendung des Operators & in Integer gewandelt werden.

ah, ok. Zuviel an Java bzw. C++ gedacht, wo die bitweise
Verknüpfung unabhängig vom Typ ist, was ja eigentlich
auch logisch ist.

> Mit pack/unpack geht sowas aber, zum Beispiel
> perl -e "print unpack('b64', pack('d', 0.1))"

Ich brauche die bitweise Addition für Demonstartionszwecke, kann
daher leider diese kurze Form nicht verwenden.

Herbert

Re: Bitfolge ausgeben

am 20.03.2006 16:46:30 von Herbert Voss

Christian Lackas wrote:

>>print binMuster(0.1)."\n";
>>print binMuster(10)."\n";
>>warum funktioniert das Ganze nicht für Fließkommazahlen?
>
>
> weil der Operator '&' nur für 'Integer Arithmetic' definiert ist (siehe
> auch perldoc perlop).

Christian,
da habe ich nun gerade mal wieder nicht nachgesehen ... :-(

> Fließkommazahlen werden idR im IEEE-Format
> gespeichert:
>
> http://www.math.byu.edu/~schow/work/IEEEFloatingPoint.htm
>
> Da macht ein bitweises Verknüpfen keinen Sinn.

Zwei Dinge spielen sehr wohl eine Rolle:
- wie kann ich mir die Bitfolge einer beliebigen skalaren Variablen
ausgeben lassen.
- Vergleich der IEEE744 mit der Realität, die für jede Sprache
anders ist: manche nehmen für die Mantisse 23Bit, andere 24.
(bzw. entsprechendes für den Exponenten)

Beides brauche ich für Demonstrationszwecke.


Herbert

Re: Bitfolge ausgeben

am 20.03.2006 20:03:29 von Christian Lackas

* Herbert Voss [2006-03-20]:

Hallo Herbert,

> > Da macht ein bitweises Verknüpfen keinen Sinn.
> Zwei Dinge spielen sehr wohl eine Rolle:

du möchtest aber gar keine bitweise Verknüpfung, sondern einfach den
internen Speicher als binäre Zahl ausgeben. Bitweise Verknüpfung macht
für Float-Zahlen wirklich keinen Sinn.

> - wie kann ich mir die Bitfolge einer beliebigen skalaren Variablen
> ausgeben lassen.

Dazu wurden dir ja pack/unpack schon genannt. Ansonsten sollte dich
sowas unter Perl normalerweise nicht interessieren. Solche
Implementierungsdetails sollen von einer Hochsprache wie Perl gerade
völlig vom User abgeschirm werden (das was du als Float benutzt könnte
ja sogar ein float Objekt sein).

> - Vergleich der IEEE744 mit der Realität, die für jede Sprache
> anders ist: manche nehmen für die Mantisse 23Bit, andere 24.
> (bzw. entsprechendes für den Exponenten)

Welche Sprachen sollen das sein? Perl verhält sich, wenig überraschend,
genau wie die libc die es verwendet. Würde mich jetzt sehr wundern, wenn
das bei anderen Sprachen anders wäre (von float Objekten z.B. mit
beliebiger Präzision mal abgesehen).

> Beides brauche ich für Demonstrationszwecke.

Warum in Perl?

Gruß
Christian

--
Pünktlichkeit ist die Kunst, richtig abzuschätzen,
um wieviel sich der andere verspäten wird.
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: Bitfolge ausgeben

am 20.03.2006 20:30:45 von Herbert Voss

Christian Lackas wrote:

> du möchtest aber gar keine bitweise Verknüpfung, sondern einfach den
> internen Speicher als binäre Zahl ausgeben. Bitweise Verknüpfung macht
> für Float-Zahlen wirklich keinen Sinn.

Christian,
ich brauche den Kram für die Ausbildung und dabei interessiert nicht
immer die _praktische_ Sinnhaftigkeit, sondern im Vordergrund
steht der Algorithmus! Und deswegen spielt die bitweise Verknüpfung
sehr wohl eine Rolle und es ist völlig uninteressant, um was für ein
Objekt es sich handelt. Selbst ein Pointer wäre hier interessant.

>>- wie kann ich mir die Bitfolge einer beliebigen skalaren Variablen
>> ausgeben lassen.
>
>
> Dazu wurden dir ja pack/unpack schon genannt. Ansonsten sollte dich

die interssieren mich ja gerade nicht! Die Frage war, wie man
mit "Bordmitteln" gleiches erreichen kann.

> sowas unter Perl normalerweise nicht interessieren. Solche
> Implementierungsdetails sollen von einer Hochsprache wie Perl gerade
> völlig vom User abgeschirm werden (das was du als Float benutzt könnte
> ja sogar ein float Objekt sein).

ist es aber hier nicht.

>>- Vergleich der IEEE744 mit der Realität, die für jede Sprache
>> anders ist: manche nehmen für die Mantisse 23Bit, andere 24.
>> (bzw. entsprechendes für den Exponenten)
>
>
> Welche Sprachen sollen das sein? Perl verhält sich, wenig überraschend,
> genau wie die libc die es verwendet. Würde mich jetzt sehr wundern, wenn
> das bei anderen Sprachen anders wäre (von float Objekten z.B. mit
> beliebiger Präzision mal abgesehen).

Es gibt keine beliebige Präzision!
Pascal und Java in den ersten Versionen, wobei das erste Pascal
sogar nur 6 Byte für eine Float hatte. Die IEEE ist eine Empfehlung,
aber keine Norm. Deswegen verlasse ich mich da nur auf Gelesenes
oder Überprüftes ... :-)

>>Beides brauche ich für Demonstrationszwecke.
>
>
> Warum in Perl?

Weil Perl nun mal das Thema des Kurses ist ... :-)

Herbert

Re: Bitfolge ausgeben

am 20.03.2006 20:51:01 von Christian Lackas

* Herbert Voss [2006-03-20]:

Hallo Herbert,

> Christian,

Herbert,

> ich brauche den Kram für die Ausbildung und dabei interessiert nicht
> immer die _praktische_ Sinnhaftigkeit, sondern im Vordergrund
> steht der Algorithmus!

Der sinnlos ist?

> Und deswegen spielt die bitweise Verknüpfung sehr wohl eine Rolle und
> es ist völlig uninteressant, um was für ein Objekt es sich handelt.
> Selbst ein Pointer wäre hier interessant.

Was soll denn in deinem tollen Algorithmus das Ergebnis von '0.1 & 1'
sein? Wo ist das definiert?

> > Dazu wurden dir ja pack/unpack schon genannt. Ansonsten sollte dich
> die interssieren mich ja gerade nicht! Die Frage war, wie man
> mit "Bordmitteln" gleiches erreichen kann.

Das sind Bordmittel. Du willst Perl benutzen, aber nicht alle
Perl-Funktionen? Welche Funktionen sind dir denn genehm? So viele
Möglichkeiten gibt es (aus gutem Grund) unter Perl nicht auf die interne
Speicherstruktur von Variablen zuzugreifen.

> > sowas unter Perl normalerweise nicht interessieren. Solche
> > Implementierungsdetails sollen von einer Hochsprache wie Perl gerade
> > völlig vom User abgeschirm werden (das was du als Float benutzt
> > könnte ja sogar ein float Objekt sein).
> ist es aber hier nicht.

Was auch ein Hinweis darauf sein könnte, dass du etwas falsch angehst.

> Es gibt keine beliebige Präzision!

Math::BigFloat, und jetzt langweile mich bitte nicht mit der endlichen
Anzahl von Baryonen in diesem Universum aus der die Begrenztheit jedes
Speichers folg. Gähn.

> Pascal und Java in den ersten Versionen, wobei das erste Pascal
> sogar nur 6 Byte für eine Float hatte.

Quellen? Ein Float (single precision, im Gegensatz zum double) besteht
heutzutage übrigens üblicherweise aus nur 4 Bytes.

> Die IEEE ist eine Empfehlung, aber keine Norm.

Es ist eine Norm (engl. 'standard').

> Deswegen verlasse ich mich da nur auf Gelesenes oder Überprüftes ... :-)

Das überlasse ich gerne dir.

> Weil Perl nun mal das Thema des Kurses ist ... :-)

Dann machst du IMHO einen großen Fehler die Leute mit Kleinscheiss zu
verwirren aus wievielen Bit die Mantisse einer Float-Zahl aufgebaut ist.

Gruß
Christian

--
Wenn ein Meister vom Himmel fällt war er mal einer.
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: Bitfolge ausgeben

am 20.03.2006 21:05:09 von Herbert Voss

Christian Lackas wrote:

>>Und deswegen spielt die bitweise Verknüpfung sehr wohl eine Rolle und
>>es ist völlig uninteressant, um was für ein Objekt es sich handelt.
>>Selbst ein Pointer wäre hier interessant.
>
>
> Was soll denn in deinem tollen Algorithmus das Ergebnis von '0.1 & 1'
> sein? Wo ist das definiert?

du hast noch nicht mal ansatzweise verstanden, wozu ich
das auf diesem Wege haben will ...

Herbert

Re: Bitfolge ausgeben

am 20.03.2006 21:11:16 von Christian Lackas

* Herbert Voss [2006-03-20]:

Hallo Herbert,

> du hast noch nicht mal ansatzweise verstanden, wozu ich
> das auf diesem Wege haben will ...

du teilst das ja auch nie mit.

Falls du nichts mehr zum Thema Perl beizutragen hast, setz doch bitte
einen Fup2p oder befolge meinen. Danke.

Gruß
Christian

--
Wer gegen ein Minimum Aluminium immun ist,
besitzt Aluminiummimimumimmunität
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: Bitfolge ausgeben

am 20.03.2006 21:22:55 von Frank Seitz

Herbert Voss wrote:

> Weil Perl nun mal das Thema des Kurses ist ... :-)

Wenn ich Dich richtig verstehe, möchtest Du in dem Kurs darstellen,
wie Perl bestimmte Dinge intern repräsentiert, z.B. Zahlen.
Wenn Du das auf Bitebene wissen willst, musst Du Dich mit
den Interna von Perl befassen. Dazu gibt es einige Dokumentation
(perldoc perl - Abschnitt "Internals and C Language Interface").
So, wie Du es von C her kennst, kannst Du das in Perl (einer
Interpretersprache) nicht untersuchen, da Perl eine Kapselung
vornimmt und mit "Bordmitteln" keinen Zugriff
auf seine Interna bietet. Diese Interna soll (und will) man
im Normalfall garnicht kennen.

Wenn Du wissen willst, was Zahlen von einer abstrakteren Ebene
aus gesehen in Perl sind, ist perldoc perlnumber vielleicht
interessant für Dich.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Bitfolge ausgeben

am 20.03.2006 22:00:10 von Herbert Voss

Frank Seitz wrote:
> Herbert Voss wrote:
>
>
>>Weil Perl nun mal das Thema des Kurses ist ... :-)
>
>
> Wenn ich Dich richtig verstehe, möchtest Du in dem Kurs darstellen,
> wie Perl bestimmte Dinge intern repräsentiert, z.B. Zahlen.
> Wenn Du das auf Bitebene wissen willst, musst Du Dich mit

Nein, will ich nicht. Perl ist an dieser Stelle nur deswegen da,
weil alles andere eben auch in Perl gemacht wird. Ziel war
hier, die interne (binäre) Darstellung von Zahlen zu überprüfen,
bzw. nachzuvollziehen.

> den Interna von Perl befassen. Dazu gibt es einige Dokumentation
> (perldoc perl - Abschnitt "Internals and C Language Interface").
> So, wie Du es von C her kennst, kannst Du das in Perl (einer
> Interpretersprache) nicht untersuchen, da Perl eine Kapselung
> vornimmt und mit "Bordmitteln" keinen Zugriff
> auf seine Interna bietet. Diese Interna soll (und will) man
> im Normalfall garnicht kennen.

Das scheint mir hier aber nicht das Problem zu sein, denn
die interne Darstellung von Integern kann ich ja einwandfrei
überprüfen. Das Problem ist a&b in Perl.

> Wenn Du wissen willst, was Zahlen von einer abstrakteren Ebene
> aus gesehen in Perl sind, ist perldoc perlnumber vielleicht
> interessant für Dich.

Ich will es ja gerade nicht abstrakt haben. Aber mein Problem
ist ohnehin mit dem Hinweis darauf, dass & nur für ganze Zahlen
funktioniert "gelöst".

Herbert

Re: Bitfolge ausgeben

am 20.03.2006 22:01:51 von Lukas Mai

Herbert Voss schrob:
> Wolf Behrenhoff wrote:
>
>> Weil & mit Integer-Zahlen arbeitet und daher Fließkommazahlen vor
>> Anwendung des Operators & in Integer gewandelt werden.
>
> ah, ok. Zuviel an Java bzw. C++ gedacht, wo die bitweise
> Verknüpfung unabhängig vom Typ ist, was ja eigentlich
> auch logisch ist.

Ist sie nicht:

.... 0.1 & 1; ...
try.c:4: error: invalid operands to binary &

.... int x = 0.1 & 1; ...
Hell.java:3: operator & cannot be applied to double,int

& ist ein Integer-Operator. Für Gleitkommazahlen oder Zeiger ist er
einfach nicht definiert, zumindest in C(++) und Java. Perl erweitert die
Funktionalität auf Strings, aber das hilft dir hier wohl auch nicht
weiter.

HTH, Lukas

Re: Bitfolge ausgeben

am 20.03.2006 23:23:48 von hjp-usenet2

Herbert Voss wrote:
> Frank Seitz wrote:
>> So, wie Du es von C her kennst, kannst Du das in Perl (einer
>> Interpretersprache) nicht untersuchen, da Perl eine Kapselung
>> vornimmt und mit "Bordmitteln" keinen Zugriff auf seine Interna
>> bietet. Diese Interna soll (und will) man im Normalfall garnicht
>> kennen.
>
> Das scheint mir hier aber nicht das Problem zu sein, denn
> die interne Darstellung von Integern kann ich ja einwandfrei
> überprüfen.

Nein, kannst Du nicht. Dass 17 & 5 == 1 ist, ist in Perl einfach so
definiert und von vollkommen unabhängig von der internen Darstellung.
Der Perl-Interpreter könnte Integerzahlen intern als Array von
Dezimalzahlen darstellen und das Ergebnis wäre trotzdem das gleiche.

> Das Problem ist a&b in Perl.

Das Problem ist, dass a&b in Perl nicht das tut, was Du erwartest. Das
tut es aber wohl nicht mal in C, da wirst Du schon auf Assembler
zurückgreifen müssen ...

hp

--
_ | Peter J. Holzer | Löschung von at.usenet.schmankerl?
|_|_) | Sysadmin WSR/LUGA |
| | | hjp@hjp.at | Diskussion derzeit in at.usenet.gruppen
__/ | http://www.hjp.at/ |

Re: Bitfolge ausgeben

am 20.03.2006 23:47:11 von Herbert Voss

Peter J. Holzer wrote:

> Nein, kannst Du nicht. Dass 17 & 5 == 1 ist, ist in Perl einfach so
> definiert und von vollkommen unabhängig von der internen Darstellung.

was heißt einfach so definiert?
& ist die bitweise Addition bzw. Und-Verknüpfung und ist im
Interpreter bzw dem Compiler über den Assembler Code AND definiert.

> Der Perl-Interpreter könnte Integerzahlen intern als Array von
> Dezimalzahlen darstellen und das Ergebnis wäre trotzdem das gleiche.
>
>
>>Das Problem ist a&b in Perl.
>
>
> Das Problem ist, dass a&b in Perl nicht das tut, was Du erwartest. Das

es macht genau das, was ich erwarte!

> tut es aber wohl nicht mal in C, da wirst Du schon auf Assembler
> zurückgreifen müssen ...

??? Seite 104 in Programmieren mit Perl von Wall,Christiansen:
"Genau wie C besitzt auch Perl Operatoren für das bitorientierte
Und (And) ..."
Das, was ich dort überlesen hatte, war eben die Umwandlung in
Integer.

Herbert

Re: Bitfolge ausgeben

am 21.03.2006 11:06:47 von Frank Seitz

Peter J. Holzer wrote:
> Herbert Voss wrote:
>>
>>Das Problem ist a&b in Perl.
>
> Das Problem ist, dass a&b in Perl nicht das tut, was Du erwartest. Das
> tut es aber wohl nicht mal in C, da wirst Du schon auf Assembler
> zurückgreifen müssen ...

Doch, in C geht das schon. In C kann man die Speicherfläche
eines Float auf die Speicherfäche eines Integer kopieren und
dann die gewünschten Bitoperationen darauf loslassen.
In C läßt sich so die Repräsenation eines Float (oder wasauchimmer)
auf Bitebene untersuchen.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Bitfolge ausgeben

am 21.03.2006 11:25:56 von Christian Lackas

* Frank Seitz [2006-03-21]:

Hallo Frank,

> Doch, in C geht das schon. In C kann man die Speicherfläche
> eines Float auf die Speicherfäche eines Integer kopieren und
> dann die gewünschten Bitoperationen darauf loslassen.

und das ist dann definiertes Verhalten?

In C++ wäre das ja ein reinterpret_cast, und die liefern nur selten
definiertes Verhalten. Sprich: Was da rauskommt kann zufällig mit den
eigenen Erwartungen übereinstimmen, es ist Compiler-Herstellern aber
völlig freigestellt was sie in der Situtation machen.


Ich kann das ganze Problem aber auch nicht nachvollziehen. Die Lösung
für das Problem ist pack, damit kommt man dann an die interne
Bitstruktur der Daten ran. Sich jetzt bockig zu stellen und zu sagen,
nein die Lösung will ich aber nicht ist doch albern. Selbst in einem
Kurs könnte man den Leuten erklären, dass man bei einer Skriptsprache
wie Perl die Daten erst in das Format wie man es von weniger hohen
Sprachen kennt umwandeln muss.

Gruß
Christian

--
Auf frischer Tat ertappt: Dunkelheit bei Einbruch verhaftet!
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: Bitfolge ausgeben

am 21.03.2006 11:38:04 von Mirco Wahab

Hallo Frank

>> Das Problem ist, dass a&b in Perl nicht das tut, was Du erwartest. Das
>> tut es aber wohl nicht mal in C, da wirst Du schon auf Assembler
>> zurückgreifen müssen ...
>
> Doch, in C geht das schon. In C kann man die Speicherfläche
> eines Float auf die Speicherfäche eines Integer kopieren und
> dann die gewünschten Bitoperationen darauf loslassen.

Meiner Meinung nach ist das zwar irgendwie richtig, aber
nicht treffend ...

Am Ende gibt es nur Speicher. Dieser besteht aus addressierbaren
Maschinenworten. Diese Maschinenworte haben "Teile" bzw. "Bits",
welche den Adressleitungen der Maschine an der Speicheradresse
entsprechen.

C/C++ ist insofern "maschinennah", als es dieses Maschinenwort-
Pradigma 1:1 durchschleift. Java gebärdet sich auch so (sieht
so aus), kann das aber doch nicht.

> In C läßt sich so die Repräsenation eines Float (oder wasauchimmer)
> auf Bitebene untersuchen.

Das ist auch richtig, aber treffender wäre es imho zu sagen,
dass C durch seine "maschinennähe" "Speicher in "maschinenre-
präsentation" sehen kann - egal, was die Anwendungsschicht
darüber meint, was dieser Speicher bedeuten soll (float, int etc.).

Das Missverständnis im Thread entstand meiner Meinung nach
aus der Ansicht der "alten Schule", dass diese "maschinenre-
präsentation" irgend etwas bedeutet, was man in einem
Kurs im Kontext von Perl vermitteln sollte.

Viele Grüße

Mirco

Re: Bitfolge ausgeben

am 21.03.2006 13:39:51 von Herbert Voss

Mirco Wahab wrote:

> Das Missverständnis im Thread entstand meiner Meinung nach
> aus der Ansicht der "alten Schule", dass diese "maschinenre-
> präsentation" irgend etwas bedeutet, was man in einem
> Kurs im Kontext von Perl vermitteln sollte.

Nein, Ziel war nur einen Minialgorithmus zu entwickeln,
der mir die Bitstruktur durch Anwendung von & ausgibt.
Ob die einen maschinennahen Bezug hat, ist uninteressant.
In einem _zweiten_ Schritt stellt sich dann die Frage,
ob Perl nicht selbst schon entsprechendes mitbringt.
Ich war aber erst beim ersten Schritt ...

Herbert

Re: Bitfolge ausgeben

am 21.03.2006 13:54:19 von Frank Seitz

Christian Lackas wrote:
> * Frank Seitz [2006-03-21]:
>>
>>Doch, in C geht das schon. In C kann man die Speicherfläche
>>eines Float auf die Speicherfäche eines Integer kopieren und
>>dann die gewünschten Bitoperationen darauf loslassen.
>
> und das ist dann definiertes Verhalten?

Ja. C ist es egal, ob die 32 Bit (beispielsweise), die der C-Compiler
für ein int reserviert hat, mit den 32 bit eines float
oder mit mit irgendwelchen anderen 32 Bit beschrieben wurden.
Generell sollte man sich bei all dem natürlich über den
Speicheraufbau (Größe, Byteorder) im klaren sein.
Als C-Programmierer kennt man den aber.

> In C++ wäre das ja ein reinterpret_cast, und die liefern nur selten
> definiertes Verhalten. Sprich: Was da rauskommt kann zufällig mit den
> eigenen Erwartungen übereinstimmen, es ist Compiler-Herstellern aber
> völlig freigestellt was sie in der Situtation machen.

Ich meinte keinen Cast, sondern memcpy().

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Bitfolge ausgeben

am 21.03.2006 14:07:23 von Wolf Behrenhoff

Herbert Voss schrieb:
> Mirco Wahab wrote:
>
>> Das Missverständnis im Thread entstand meiner Meinung nach
>> aus der Ansicht der "alten Schule", dass diese "maschinenre-
>> präsentation" irgend etwas bedeutet, was man in einem
>> Kurs im Kontext von Perl vermitteln sollte.
>
> Nein, Ziel war nur einen Minialgorithmus zu entwickeln,
> der mir die Bitstruktur durch Anwendung von & ausgibt.
> Ob die einen maschinennahen Bezug hat, ist uninteressant.

Sowas hat aber grundsätzlich einen maschinennahen Bezug, denn irgendwie
müssen die Floats ja dargestellt werden im Speicher.

Das ist aber für einen Perl-Programmierer völlig irrelevant, du weißt ja
normalerweise nicht einmal, ob $x ein String, eine Referenz, ein Integer
oder ein Float ist (von so Dingen wie "use integer" oder "ref" mal
abgesehen). Somit MUSS ein Operator sinnvollerweise festlegen, welchen
Typ er verwenden soll. Und bei & ist dies eben Integer.

> In einem _zweiten_ Schritt stellt sich dann die Frage,
> ob Perl nicht selbst schon entsprechendes mitbringt.
> Ich war aber erst beim ersten Schritt ...

Du musst auch in anderen Hochsprachen zunächst casten, um bitweises and
zu machen. Natürlich kannst du das auch in Perl tun, vielleicht kommst
du ja dann deinem Ziel näher!

Ich meine folgendes:
print binMuster(unpack('L',pack('f', 1.1)));

Damit sagst du Perl, dass es einen 32-bittigen Float in einen
32-bittigen Integer (unsigned) umwandeln willst.

Wolf

Re: Bitfolge ausgeben

am 21.03.2006 14:14:12 von Christian Lackas

* Frank Seitz [2006-03-21]:

Hallo Frank,

> > und das ist dann definiertes Verhalten?
> Ja. C ist es egal, ob die 32 Bit (beispielsweise), die der C-Compiler
> für ein int reserviert hat, mit den 32 bit eines float
> oder mit mit irgendwelchen anderen 32 Bit beschrieben wurden.

das sowas mit C geht ist klar, dass es dem C-Compiler egal ist wage ich
zu bezweifeln. Du musst ihn idR schon zwingen sowas zu tun, z.B. durch
umcasten des Inhalts. Dann machst du dem Compiler aber vor du weisst was
du tust und er führt es dann pflichtschuldigst aus. Vom ISO C Standard
abgedeckt ist das aber noch lange nicht.

> > In C++ wäre das ja ein reinterpret_cast, und die liefern nur selten
> > definiertes Verhalten. Sprich: Was da rauskommt kann zufällig mit den
> > eigenen Erwartungen übereinstimmen, es ist Compiler-Herstellern aber
> > völlig freigestellt was sie in der Situtation machen.
> Ich meinte keinen Cast, sondern memcpy().

Das ist ja noch schlimmer. Sowas ist mit Sicherheit nicht vom Standard
abgedeckt.
Ein reinterpret_cast würde das gleiche tun, auch ohne das du die Daten
erst zu (void *), kopieren und wieder zurückcasten (oder bei dir schon
vorher eine Variable des Typs anlegen) musst.


Gruß
Christian

--
Entwicklungshilfe nimmt das Geld der Armen in den reichen Ländern und
gibt es den Reichen in den armen Ländern.
(Achmed Mohamed Saleh, Journalist aus Tansania)
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: Bitfolge ausgeben

am 21.03.2006 14:20:10 von Wolf Behrenhoff

Wolf Behrenhoff schrieb:
> Das ist aber für einen Perl-Programmierer völlig irrelevant, du weißt ja
> normalerweise nicht einmal, ob $x ein String, eine Referenz, ein Integer
> oder ein Float ist (von so Dingen wie "use integer" oder "ref" mal
> abgesehen). Somit MUSS ein Operator sinnvollerweise festlegen, welchen
> Typ er verwenden soll. Und bei & ist dies eben Integer.

Argh. Selbstkorrektur: natürlich geht & auch mit Strings. Allerdings nur
mit zwei Strings. Wenn du string&intger machst, wird versucht, String in
eine Zahl zu wandeln.

Trotzdem: dies zeigt, warum es in Perl Operatorüberladung kaum gibt.

Wolf

Re: Bitfolge ausgeben

am 21.03.2006 17:58:32 von hjp-usenet2

Herbert Voss wrote:

> Peter J. Holzer wrote:
>> Nein, kannst Du nicht. Dass 17 & 5 == 1 ist, ist in Perl einfach so
>> definiert und von vollkommen unabhängig von der internen Darstellung.
>
> was heißt einfach so definiert?
> & ist die bitweise Addition bzw. Und-Verknüpfung und ist im
> Interpreter bzw dem Compiler über den Assembler Code AND definiert.

Nein, Es ist definiert, wie das *Ergebnis* lauten muss, nicht auf welche
Art der Compiler dieses Ergebnis zustandebringt. Zumindest in C
(Perl hat keine formale Spezifikation, und perldoc perlop definiert das
nicht näher sondern verlässt sich darauf, dass dem Leser das ohnehin
klar ist).

Skalare in Perl haben ja gar keine Typen wie "integer" oder "float" oder
"string", bzw. sie können mehrere dieser Typen gleichzeitig haben. Wenn
Du z.B. folgendes Script laufen lässt:

#!/usr/bin/perl -w
use strict;
use warnings;
use Devel::Peek;

my $x = '17';
print Dump($x);

my $y = $x & 5;
print Dump($x);
print Dump($y);

Dann siehst Du, dass $x beim ersten Dump einen String mit dem Wert '17'
enthält. Das Bitmuster dieses Strings mit dem Bitmuster der Zahl 5
(dargestellt im Zweierkomplementsystem) zu verunden, wäre zwar
zweifellos möglich, aber das Ergebnis hinge von der Endianness ab und
wäre in keinem Fall ein sonderlich sinnvolles. Daher wird $x als
Integerzahl interpretiert und die &-Operation in binärer
Integerarithmetik durchgeführt. Im nächsten Dump siehst Du dann, dass $x
nun zwei Werte enthält: Den String '17' und den Integerwert 17. $y
hingegen ist ein reiner Integerwert (1).

Im Gegensatz zu C, wo ein Objekt vom Typ int einfach nur aus ein paar
Bytes Speicher besteht, die den Wert des Objekts repräsentieren (bei
32-Bit-Ints und 8-Bit-Bytes also 4 Bytes) und jegliche Typinformation
nur der Compiler (bzw. implizit der von ihm erzeugte Code) hat, führen
Perl-Skalare Typinformationen (und andere Informationen) mit. Ein
Perl-Skalar kann sich (in perl5) auf 2 oder 3 vollkommen getrennte
Speicherbereiche erstrecken.

>>>Das Problem ist a&b in Perl.
>>
>> Das Problem ist, dass a&b in Perl nicht das tut, was Du erwartest.
>
> es macht genau das, was ich erwarte!

Wo ist dann Dein Problem?


>> tut es aber wohl nicht mal in C, da wirst Du schon auf Assembler
>> zurückgreifen müssen ...
>
> ??? Seite 104 in Programmieren mit Perl von Wall,Christiansen:
> "Genau wie C besitzt auch Perl Operatoren für das bitorientierte
> Und (And) ..."

Und genau wie in C sind sie auf Integerwerte definiert, nicht auf
interne Bitrepräsentation.

hp

--
_ | Peter J. Holzer | Löschung von at.usenet.schmankerl?
|_|_) | Sysadmin WSR/LUGA |
| | | hjp@hjp.at | Diskussion derzeit in at.usenet.gruppen
__/ | http://www.hjp.at/ |

Re: Bitfolge ausgeben

am 21.03.2006 18:10:35 von hjp-usenet2

Frank Seitz wrote:

> Christian Lackas wrote:
>> * Frank Seitz [2006-03-21]:
>>>Doch, in C geht das schon. In C kann man die Speicherfläche
>>>eines Float auf die Speicherfäche eines Integer kopieren und
>>>dann die gewünschten Bitoperationen darauf loslassen.
>>
>> und das ist dann definiertes Verhalten?
>
> Ja.

Nein. Wenn Du auf ein Objekt mittels eines anderen Typs zugreifst, als
Du zum Schreiben verwendet hast, ist das Verhalten undefiniert.

Einzige Ausnahme: Du darfst jedes Objekt als Array von unsigned char
behandeln.

> C ist es egal, ob die 32 Bit (beispielsweise), die der C-Compiler
> für ein int reserviert hat, mit den 32 bit eines float
> oder mit mit irgendwelchen anderen 32 Bit beschrieben wurden.

Das kannst Du machen, wenn Du mit memcpy kopierst, denn in dem Fall
behandelst Du die 32 Bit als array von 4 unsigned char. Nachdem Du den
float-Wert reinkopiert hast, darfst Du den Platz aber nicht mehr als int
verwenden. Das Ergebnis ist undefiniert: Vielleicht bekommst Du das
Bitmuster des Float, vielleicht einen Coredump, vielleicht benennt sich
das Programm in /bin/laden um und schickt Liebesbriefe an den
amerikanischen Präsidenten.

> Als C-Programmierer kennt man den aber.

Man sollte sich dann aber darüber im klaren sein, dass man dann nicht
mehr C programmiert, sondern für eine spezielle Klasse von
C-Implementationen, wenn nicht gar für einen speziellen Compiler.

hp

PS: http://www.hjp.at/programs/ieeefloat/

--
_ | Peter J. Holzer | Löschung von at.usenet.schmankerl?
|_|_) | Sysadmin WSR/LUGA |
| | | hjp@hjp.at | Diskussion derzeit in at.usenet.gruppen
__/ | http://www.hjp.at/ |

Re: Bitfolge ausgeben

am 21.03.2006 18:14:14 von hjp-usenet2

Christian Lackas wrote:
> * Frank Seitz [2006-03-21]:
>> > und das ist dann definiertes Verhalten?
>> Ja. C ist es egal, ob die 32 Bit (beispielsweise), die der C-Compiler
>> für ein int reserviert hat, mit den 32 bit eines float
>> oder mit mit irgendwelchen anderen 32 Bit beschrieben wurden.
>
> das sowas mit C geht ist klar, dass es dem C-Compiler egal ist wage
> ich zu bezweifeln. Du musst ihn idR schon zwingen sowas zu tun, z.B.
> durch umcasten des Inhalts.

Nein, nicht durch einen Cast. Ein Cast ist eine (typischerweise
wert-erhaltende) Umwandlungsfunktion. (int)3.14 ergibt den int-Wert 3,
nicht den int-Wert, der das gleiche Bitmuster wie die float-Zahl 3.14
hat. Dafür brauchst Du aliasing (über pointer oder unions) oder memcpy.

hp

--
_ | Peter J. Holzer | Löschung von at.usenet.schmankerl?
|_|_) | Sysadmin WSR/LUGA |
| | | hjp@hjp.at | Diskussion derzeit in at.usenet.gruppen
__/ | http://www.hjp.at/ |

Re: Bitfolge ausgeben

am 21.03.2006 18:24:14 von Ingo Menger

Herbert Voss schrieb:

> Christian Lackas wrote:
>
> > du möchtest aber gar keine bitweise Verknüpfung, sondern einfach den
> > internen Speicher als binäre Zahl ausgeben. Bitweise Verknüpfung ma=
cht
> > für Float-Zahlen wirklich keinen Sinn.
>
> Christian,
> ich brauche den Kram für die Ausbildung

Offenbar hast Du selbst noch eine Menge Ausbildung nötig.

> und dabei interessiert nicht
> immer die _praktische_ Sinnhaftigkeit, sondern im Vordergrund
> steht der Algorithmus!

Dazu müßte es aber erst mal einen geben!
Dein halluzinierter Algorithmus basiert auf der /falschen/ Idee, daß
man mittels des & Operators irgendwelche Informationen über die
binäre Darstellung der Perl-Daten herausfinden könnte.

Wie falsch die Idee ist, siehst Du an folgendem Beispiel:

perl -e "print 'xxx' + 3;"

Dies gibt 3 aus. Also ist 'xxx' repräsentiert als (binär) 0?!
Die Idee, daß man mittels des + Operators irgendwelche Informationen
über die interne Repräsentation von Perl-Daten herausfinden kann, ist
offensichtlich falsch.
Und jetzt alle: Die Idee, daß man mittels des & Operators ...

Re: Bitfolge ausgeben

am 21.03.2006 19:33:37 von Frank Seitz

Peter J. Holzer wrote:
> Frank Seitz wrote:
>>
>>C ist es egal, ob die 32 Bit (beispielsweise), die der C-Compiler
>>für ein int reserviert hat, mit den 32 bit eines float
>>oder mit mit irgendwelchen anderen 32 Bit beschrieben wurden.
>
> Das kannst Du machen, wenn Du mit memcpy kopierst, denn in dem Fall
> behandelst Du die 32 Bit als array von 4 unsigned char. Nachdem Du den
> float-Wert reinkopiert hast, darfst Du den Platz aber nicht mehr als int
> verwenden.

Wieso das? Jedes Bitmuster über den vier Bytes ist ein
gültiger int-Wert, wenn ich nicht irre. Mein letztes C-Programm
liegt einige Jahre zurück, deshalb bin ich in den Details
nicht mehr so drin, aber ich meine, folgender Code müsste
portabel funktionieren (sofern sizeof(int) == sizeof(float)):

unsigned int i;
float f = 0.1;
memcpy(&i,&f,sizeof(i));
/* auf i steht IEEE 754 float,
Bitoperatoren sind anwendbar */

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Bitfolge ausgeben

am 21.03.2006 20:10:03 von Roman Racine

Frank Seitz schrieb:

> Christian Lackas wrote:
>> * Frank Seitz [2006-03-21]:
>>>
>>>Doch, in C geht das schon. In C kann man die Speicherfläche
>>>eines Float auf die Speicherfäche eines Integer kopieren und
>>>dann die gewünschten Bitoperationen darauf loslassen.
>>
>> und das ist dann definiertes Verhalten?
>
> Ja. C ist es egal, ob die 32 Bit (beispielsweise), die der C-Compiler
> für ein int reserviert hat, mit den 32 bit eines float
> oder mit mit irgendwelchen anderen 32 Bit beschrieben wurden.

Das hat rein theoretisch kein definiertes Verhalten, da die
Programmiersprache C nicht garantiert, dass ein Integer 32 Bit breit ist
(ob zwingend IEEE Floatingpoint-Arithmetik zur Anwendung kommt, weiss ich
gerade nicht). Tatsächlich wird das aber trotzdem auf den gängigen
Betriebssystemen funktionieren. BTW kann man dazu auch einen Union
verwenden, etwa so:

#include
#include

union test {
uint32_t an_int;
float a_float;
};

int main(void)
{
union test bla;
uint32_t blubb;
bla.a_float = 0.3;
blubb = bla.an_int;
for (int i = 31; i >= 0; i--)
printf("%d",(blubb>>i) & 1);
puts("");
return 0;
}

Gruss

Roman°
--
IRC-Freenode: #usenet-friends
http://albasani.net/cgiirc/irc.cgi

Re: Bitfolge ausgeben

am 21.03.2006 20:56:20 von hjp-usenet2

Frank Seitz wrote:

> Peter J. Holzer wrote:
>> Frank Seitz wrote:
>>>
>>>C ist es egal, ob die 32 Bit (beispielsweise), die der C-Compiler
>>>für ein int reserviert hat, mit den 32 bit eines float
>>>oder mit mit irgendwelchen anderen 32 Bit beschrieben wurden.
>>
>> Das kannst Du machen, wenn Du mit memcpy kopierst, denn in dem Fall
>> behandelst Du die 32 Bit als array von 4 unsigned char. Nachdem Du
>> den float-Wert reinkopiert hast, darfst Du den Platz aber nicht mehr
>> als int verwenden.
>
> Wieso das? Jedes Bitmuster über den vier Bytes ist ein
> gültiger int-Wert, wenn ich nicht irre.

Du irrst. Der C-Standard garantiert nicht, dass das so ist. Tatsächlich
hat es C-Implementationen gegeben, die einzelne Bits ausgelassen haben
und wenn ich mich recht entsinne auch solche, die "signalling NaNs" bei
Integers hatten.

Dass auf so ziemlich jedem Prozessor, den Du heutzutage kaufen kannst,
jede mögliche Kombination der 32 Bit einen gültigen (und verschiedenen)
Integer-Wert repräsentiert, heißt nicht, dass das notwendigerweise so
sein muss. Es gab in den 70er und 80er-Jahren ziemlich viel perverse
Hardware, und für die wurden auch C-Compiler entwickelt.

| 10 Thou shalt foreswear, renounce, and abjure the vile heresy which
| claimeth that ``All the world's a VAX'', and have no commerce with
| the benighted heathens who cling to this barbarous belief, that the
| days of thy program may be long even though the days of thy current
| machine be short.

("The 10 Commandments for C Programmers" von Henry Spencer. Annotated
Edition auf http://www.lysator.liu.se/c/ten-commandments.html)

> Mein letztes C-Programm liegt einige Jahre zurück,

Bei mir auch. Insbesondere beziehe ich mich auf C89. Es kann sein, dass
sich bei C99 in dieser Beziehung etwas geändert hat, glaube es aber
nicht.

> deshalb bin ich in den Details nicht mehr so drin, aber ich meine,
> folgender Code müsste portabel funktionieren (sofern sizeof(int) ==
> sizeof(float)):
>
> unsigned int i;
> float f = 0.1;
> memcpy(&i,&f,sizeof(i));

Der Code ist schon deswegen nicht portabel, weil sizeof(i) nicht
notwendigerweise gleich sizeof(f) ist. Wenn sizeof(i) > sizeof(f) (was
unwahrscheinlich, aber möglich ist (Hmm, Cray vielleicht?)), greifst Du
über das Ende von f hinaus zu, was zu undefiniertem Verhalten führt.
(Der umgekehrte Fall, dass sizeof(i) < sizeof(f) ist, was deutlich
wahrscheinlicher ist/wahr, ist unkritisch: Dann wird halt nur ein Teil
von f kopiert).

> /* auf i steht IEEE 754 float,
> Bitoperatoren sind anwendbar */

Der Kommentar ist in einem portablen Programm schlicht falsch. Nicht
alle C-Implementationen verwenden IEEE-754. Der gcc auf
DEC/digital/Compaq/HP Alpha z.B. verwendet zwar per default die
Zahlendarstellung, rechnet aber anders (darüber bin ich vor ein paar
Jahren bei POVray gestolpert). Da die Alpha die alten VAX-FP-Formate
versteht, kann man ihm vermutlich auch sagen, dass er die verwenden
soll.

Weiters wäre danach ein

printf("%x\n", i & 0x1);

nicht portabel. Das könnte einen Core-Dump oder schlimmeres
verursachen. (unwahrscheinlich, ja. Aber vom Standard gedeckt)

hp

--
_ | Peter J. Holzer | Löschung von at.usenet.schmankerl?
|_|_) | Sysadmin WSR/LUGA |
| | | hjp@hjp.at | Diskussion derzeit in at.usenet.gruppen
__/ | http://www.hjp.at/ |

Re: Bitfolge ausgeben

am 21.03.2006 22:17:09 von Christian Lackas

* Peter J. Holzer [2006-03-21]:

Hallo Peter,

> > das sowas mit C geht ist klar, dass es dem C-Compiler egal ist wage
> > ich zu bezweifeln. Du musst ihn idR schon zwingen sowas zu tun, z.B.
> > durch umcasten des Inhalts.
> Nein, nicht durch einen Cast.

doch, mit dem genannten reinterpret_cast:

float f = 20.5;
int* ptx = reinterpret_cast(&f);

> Ein Cast ist eine (typischerweise wert-erhaltende)
> Umwandlungsfunktion. (int)3.14 ergibt den int-Wert 3,

Das wäre dann ein standard C Cast, wobei man unter C++ (und darüber
sprach ich ja) für dein Beispiel dann einen static_cast machen würde.
Der aber, wie du ja schreibst, völlig anders funktioniert.

> nicht den int-Wert, der das gleiche Bitmuster wie die float-Zahl 3.14
> hat.

Mit obigem Cast schon.

> Dafür brauchst Du aliasing (über pointer oder unions) oder memcpy.

Natürlich verwendet man für einen reinterpret_cast einen Pointer. Wer
sollte etwas anderes behaupten?

Gruß
Christian

--
Ich bin ganz und gar nicht Ihrer Meinung aber ich würde mein Leben dafür
geben, dass Sie sie äußern dürfen. Voltaire
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: Bitfolge ausgeben

am 22.03.2006 23:29:08 von hjp-usenet2

Christian Lackas wrote:

> * Peter J. Holzer [2006-03-21]:
>
> Hallo Peter,
>
>> > das sowas mit C geht ist klar, dass es dem C-Compiler egal ist wage
^ ^^^^^^^^^^
>> > ich zu bezweifeln. Du musst ihn idR schon zwingen sowas zu tun,
>> > z.B. durch umcasten des Inhalts.
>> Nein, nicht durch einen Cast.
>
> doch, mit dem genannten reinterpret_cast:
>
> float f = 20.5;
> int* ptx = reinterpret_cast(&f);

Das ist nicht C.

>> Ein Cast ist eine (typischerweise wert-erhaltende)
>> Umwandlungsfunktion. (int)3.14 ergibt den int-Wert 3,
>
> Das wäre dann ein standard C Cast, wobei man unter C++ (und darüber
> sprach ich ja)

Da oben steht zweimal "C" und nirgends "C++". Wenn Du von C++ redest,
solltest Du es auch "C++" nennen und nicht "C". C und C++ sind
verschiedene Sprachen.

hp

--
_ | Peter J. Holzer | Löschung von at.usenet.schmankerl?
|_|_) | Sysadmin WSR/LUGA |
| | | hjp@hjp.at | Diskussion derzeit in at.usenet.gruppen
__/ | http://www.hjp.at/ |

Re: Bitfolge ausgeben

am 23.03.2006 10:08:58 von Christian Lackas

* Peter J. Holzer [2006-03-22]:

Hallo Peter,

> > doch, mit dem genannten reinterpret_cast:
> > float f = 20.5;
> > int* ptx = reinterpret_cast(&f);
> Das ist nicht C.

das ist schön, dass du das jetzt auch schon siehst.

> > > Ein Cast ist eine (typischerweise wert-erhaltende)
> > > Umwandlungsfunktion. (int)3.14 ergibt den int-Wert 3,
> > Das wäre dann ein standard C Cast, wobei man unter C++ (und darüber
> > sprach ich ja)
> Da oben steht zweimal "C" und nirgends "C++". Wenn Du von C++ redest,
> solltest Du es auch "C++" nennen und nicht "C".

Das C hier stammt von Frank, ich habe das reinterpret_cast eindeutig --
wie du gerne nachlesen kannst (<20060321T101758@lackas.net>) -- als C++
Feature eingeführt. Da in dieser Sprache die Casts besser strukturiert
sind und sag *ich* es daher sinnvoller an hiermit zu argumentieren
(ansonsten ist für den hier relevanten Teil C ein Subset von C++, so
dass das keine Einschränkung der Allgemeinheit darstellte, insbesondere
gibt es die 'standard C Casts' auch unter C++).

Wenn du zu einem Thread etwas sinnvolles beitragen möchtest, dann
solltest du ihn bitte vorher lesen. Du hast sicher Verständnis dafür,
dass ich nicht speziell für dich nochmal den kompletten Zusammenhang in
jedem Posting aufführen kann.

> C und C++ sind verschiedene Sprachen.

Jetzt wo du es sagst...

Wir schweifen ab, bitte beachte meinen oder setzte einen anderen Fup2,
falls du nicht wieder auf Perl zurückkommen möchtest. Da ich auch in
anderen Newsgroups keinen Bedarf an dieser Diskussion sehe, setzte ich
einen Fup2p.

Gruß
Christian

--
Murphys Law 5: Jedes Programm, in das sich ein Fehler einschleichen kann,
wird auch einen enthalten.
Folgerung: Jeder Fehler wird dort sitzen, wo er am spätesten entdeckt
wird und den größtmöglichen Schaden anrichtet.

Re: Bitfolge ausgeben

am 26.03.2006 00:04:41 von Thomas Jahns

Frank Seitz writes:
> Wieso das? Jedes Bitmuster über den vier Bytes ist ein
> gültiger int-Wert, wenn ich nicht irre. Mein letztes C-Programm
> liegt einige Jahre zurück, deshalb bin ich in den Details
> nicht mehr so drin, aber ich meine, folgender Code müsste
> portabel funktionieren (sofern sizeof(int) == sizeof(float)):

Aber der Punkt ist hier doch gerade, daß eben solche Annahmen nicht
universell gültig sind.

Thomas Jahns
--
"Computers are good at following instructions,
but not at reading your mind."
D. E. Knuth, The TeXbook, Addison-Wesley 1984, 1986, 1996, p. 9

Re: Bitfolge ausgeben

am 26.03.2006 00:11:52 von Thomas Jahns

Roman Racine writes:
> Das hat rein theoretisch kein definiertes Verhalten, da die
> Programmiersprache C nicht garantiert, dass ein Integer 32 Bit breit ist

z.B. nicht für MS-DOS mit typischen C-Compilern der damaligen Zeit:
CHAR_BIT==8, sizeof(int)==2

> (ob zwingend IEEE Floatingpoint-Arithmetik zur Anwendung kommt, weiss ich

z.B. nicht auf Motorola 68k (eigene 80bit-Implementierung IIRC, keine
Ahnung ob das für deren aktuellen Embedded-Abkömmling Dragonball
geändert wurde). C ist so gestaltet, daß IEEE754 gut funktioniert, aber
nicht zwingend vorausgesetzt wird.

> gerade nicht). Tatsächlich wird das aber trotzdem auf den gängigen
> Betriebssystemen funktionieren. BTW kann man dazu auch einen Union
> verwenden, etwa so:

Man sollte in einen Union nur hineintun, was man auch genauso
wieder herausholen will.

Thomas Jahns
--
"Computers are good at following instructions,
but not at reading your mind."
D. E. Knuth, The TeXbook, Addison-Wesley 1984, 1986, 1996, p. 9

Re: Bitfolge ausgeben

am 26.03.2006 00:11:54 von Thomas Jahns

Frank Seitz writes:
> Doch, in C geht das schon. In C kann man die Speicherfläche
> eines Float auf die Speicherfäche eines Integer kopieren und
> dann die gewünschten Bitoperationen darauf loslassen.
> In C läßt sich so die Repräsenation eines Float (oder wasauchimmer)
> auf Bitebene untersuchen.

Dieses kopieren ist aber hochgradig implementationsabhängig. Nicht alle
Plattformen bieten 4 Byte float, nicht auf jeder Plattform muss es einen
Integer mit den gleichen Alignment-Anforderungen wie ein float geben
(z.B. wenn der kleinste Fließkommatyp 8 Byte und der größte Ganzzahltyp
4 Byte benötigt) und vor allem sind durch die bit order (msb/lsb first) auch
die Ergebnisse nicht notwenigerweise definiert, wenn die beiden erstgenannten
Anforderungen erfüllt sind.

C definiert auch nicht genügend Funktionen, um die Mantisse auf direktem
Wege zu extrahieren und in einem integralen Typ abzulegen.
Für Vorzeichen und Exponent ist es mit Hilfe von ilogb zwar möglich,
aber für die Mantisse gibt es keinen Typ, der garantiert genügend bits
hat, weshalb ich hier Bibliotheken wie Sun's XDR empfehlen
würde. Alternativ kann man natürlich versuchen, einzelne 2^-n Bits zu
extrahieren und in 8er-Gruppen in unsigned char-arrays zu speichern.

Ich erinnere mich immer noch gerne an jemanden der seine ganze
Applikation auf der Verfügbarkeit von 80bit long double aufgebaut hatte
und dann beim Portieren auf POWER etwas ins Schwitzen geriet.

Thomas Jahns
--
"Computers are good at following instructions,
but not at reading your mind."
D. E. Knuth, The TeXbook, Addison-Wesley 1984, 1986, 1996, p. 9