PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bitgenauer float-Array mittels Hexadezimaldarstellung



Gonse
18-02-2008, 15:15
Hallo zusammen,

ich muss Daten vom Typ float von Matlab nach C exportieren.
Ich dachte, es wäre schlau dies in hexadezimaler Schreibweise nach IEEE 754 zu bewerkstelligen.
Das REsultat sieht dann so aus:



// Systemmatrix der Strecke (transponiert, hex)
static real AD[NumberOfStates * NumberOfStates] = {
0x402c6eb4, 0x40000000, 0x00000000,
0xbf9adbec, 0x00000000, 0x3f000000,
0x3f396f83, 0x00000000, 0x00000000
};


Das Problem ist, dass der Compiler die Daten als Integer interpretiert und diese nach float castet.
Was ich aber will ist, dass diese Daten direkt als float-Zahlen übernommen werden.

Habe ich mein Anliegen deutlich genug erklärt? Weiss jemand Abhilfe?

Gruß,
Stefan

jeebee
18-02-2008, 16:38
http://info.baeumle.com/c03.html[/URL]"]Ganzzahlkonstanten können auch oktal und hexadezimal angegeben werden. (Freude kommt auf!) Beginnt eine ganzzahlige Konstante mit einer 0, so wird sie als Oktalzahl interpretiert: 007 ist dezimal 7, 010 ist dezimal 8. Beginnt sie dagegen mit 0x oder 0X, so wird sie hexadezimal interpretiert: 0x1f oder 0x1F stehen für den dezimalen Wert 1*16+15*1=31.

Gleitpunktkonstanten enthalten einen Dezimalpunkt (123.45) und/oder einen Exponenten (12E-2 steht für 0.12, 1.234E2 steht für 123.4). Ohne ein spezielles Suffix sind diese vom Typ double, mit dem Suffix F (oder f) float, mit L vom Typ long double!



Also, Hexadezimale Schreibweise ist nur für ganzzahlige Konstanten möglich (char, short, int, long).
Was eigentlich funktionieren sollte, ist die Daten einfach in E-Schreibweise (1.234E-5) auszugeben und so weiterzuverwenden. Dabei sollte doch kein Präzisionsverlust auftreten (Ausgeben kannst du ja immer die volle Genauigkeit des gewählten Formats, und der Kompiler sollte auch die Genauigkeit des Formats ausnützen.)

Zu deinem Code: In C gibts keinen Typ real, sondern nur float (häufig IEEE 754 single precision) und double (häufig IEEE 754 double precision). Es ist aber zu beachten das der C-Standard nicht IEEE 754 zur Speicherung von Floating-Point-Werten vorschreibt.
For example, the C programming language, which pre-dated IEEE 754, now allows but does not require IEEE arithmetic (the C float typically is used for IEEE single-precision and double uses IEEE double-precision).

Gonse
18-02-2008, 22:46
Also, Hexadezimale Schreibweise ist nur für ganzzahlige Konstanten möglich (char, short, int, long).

Sehr ernüchternd. Wäre viel eleganter.



Was eigentlich funktionieren sollte, ist die Daten einfach in E-Schreibweise (1.234E-5) auszugeben und so weiterzuverwenden. Dabei sollte doch kein Präzisionsverlust auftreten (Ausgeben kannst du ja immer die volle Genauigkeit des gewählten Formats, und der Kompiler sollte auch die Genauigkeit des Formats ausnützen.)


Die Genauigkeit, also die Auflösung, hängt auch von der Zahl ab. Aber mir wird wohl nichts anderes übrig bleiben.



Zu deinem Code: In C gibts keinen Typ real, sondern nur float ...


real entspricht bei mir float. Diese Nomenklatur ist auf Lapack/Blas zurückzuführen.

Danke für die Mühe und wenn jemand noch ein Trick einfällt, dann raus damit.

Gruß,
Stefan

Eselchen
19-02-2008, 01:36
Wuerde ein

reinterpret_cast<float>(0x????????)

funktionieren?


Entschuldigung, ich lese "C" und nicht "C++"

-My bad

Gonse
19-02-2008, 07:37
Danke für den Versuch. Vielleicht ein anderer?

Gruß,
Stefan

Eselchen
19-02-2008, 10:14
Einen hab ich noch. Du kannst doch versuchen den reinterpret_cast in C nachzubauen.




int *int_daten = (int *) malloc(n*sizeof(int));
float *float_daten = (float *) int_daten;



Gruesse,

Eselchen

Gonse
20-02-2008, 11:43
Ja, das geht.

Werde den GEdanken auf jeden Fall festhalten, aber mal sehen, ob ich es jetzt noch einmal umstricke.

Danke auf jeden Fall,
Stefan

Hun
22-02-2008, 21:08
ohne malloc:



int t = 0x402c6eb4;
float foo = *(float *) &t;


Lass das in ner schleife laufen und es sollte das problem beheben.