Hallo liebe Gemeinde, ich habe eine Datei bekommen, in der 64 Bit float Zahlen gespeichert sind. Ich kenne also nur die Hexwerte aus der Datei und ihren Dez Wert. Ich habe aber nicht für alle erdenklichen Werte das Dez äquivalent. Frage ist nun, wie kann ich aus der Hex/Byte Darstellung die korrekte float Zahl berechnen? Ich habe mich schon in IEEE754 eingelesen, bekomme aber leider nicht raus, was Mantisse oder der Exponent ist bei meinen Werten ist. Getestet habe ich mit: http://www.h-schmidt.net/FloatConverter/IEEE754de.html Meine Werte aus der Datei sind ähnlich der Kodierung im VC++ V13. Im Moment gehe ich davon aus, dass die floats nicht gemäß IEEE754 gespeichert wurden. Anbei eine Tabelle mit einigen Werten (Dez, Hex, Bin). Danke für eure Hilfe! Ich bin schon 2 Tage dran und komme nicht auf die Lösung. Grüße Martin Wertebeispiele: Dez Hex Bin -10 : 00 00 00 00 00 00 24 C0 -5 : 00 00 00 00 00 00 14 C0 -4 : 00 00 00 00 00 00 10 C0 00000000000000000000000000000000000000000000000000010000 11000000 -3 : 00 00 00 00 00 00 08 C0 00000000000000000000000000000000000000000000000000001000 11000000 -2 : 00 00 00 00 00 00 00 C0 00000000000000000000000000000000000000000000000000000000 11000000 -1,001: 6A BC 74 93 18 04 F0 BF 01101010101111000111010010010011000110000000010011110000 10111111 -1,000: 00 00 00 00 00 00 F0 BF 00000000000000000000000000000000000000000000000011110000 10111111 -0,999: 2B 87 16 D9 CE F7 EF BF 00101011100001110001011011011001110011101111011111101111 10111111 -0,002: FC A9 F1 D2 4D 62 60 BF 11111100101010011111000111010010010011010110001001100000 10111111 -0,001: FC A9 F1 D2 4D 62 50 BF 11111100101010011111000111010010010011010110001001010000 10111111 0,000 : 0 0,001 : FC A9 F1 D2 4D 62 50 3F 11111100101010011111000111010010010011010110001001010000 00111111 1,000 : 00 00 00 00 00 00 F0 3F 00000000000000000000000000000000000000000000000011110000 00111111 1,998 : 2B 87 16 D9 CE F7 FF 3F 00101011100001110001011011011001110011101111011111111111 00111111 1,999 : 96 43 8B 6C E7 FB FF 3F 10010110010000111000101101101100111001111111101111111111 00111111 2,000 : 00 00 00 00 00 00 00 40 00000000000000000000000000000000000000000000000000000000 01000000 3 : 00 00 00 00 00 00 08 40 00000000000000000000000000000000000000000000000000001000 01000000 4 : 00 00 00 00 00 00 10 40 00000000000000000000000000000000000000000000000000010000 01000000 5 : 00 00 00 00 00 00 14 40 00000000000000000000000000000000000000000000000000010100 01000000 10 : 00 00 00 00 00 00 24 40 33 : 00 00 00 00 00 80 40 40 00000000000000000000000000000000000000001000000001000000 01000000
-10 und 10 unterscheiden sich im obersten Bit des letzten Bytes. Ich würde es man mit little endian IEEE754 double probieren.
Probier's mal hiermit. http://www.zogg-jm.ch/IEEE_754_Umwandlung_Gleitkomma_zu_32_u_64_Bit.html Oliver
Bist du dir sicher dass es sich um float handelt? Probiere es mal mit double.
Martin U. schrieb: > Getestet habe ich mit: > http://www.h-schmidt.net/FloatConverter/IEEE754de.html Dieser Converter verarbeitet aber nur 32 Bit Zahlen, Du hast aber anscheinend 64 Bit Werte.
1 Bit Vorzeichen 11 Bit Exponent Rest Mantisse ohne führende 1
Martin U. schrieb: > ich habe eine Datei bekommen, in der 64 Bit float Zahlen gespeichert > sind. > Ich kenne also nur die Hexwerte aus der Datei und ihren Dez Wert. > > Ich habe aber nicht für alle erdenklichen Werte das Dez äquivalent. Vielleicht bin ich da etwas "zurückgeblieben" - aber Schnittstellen "vereinbart" man üblicherweise. Also ist genau definiert, was gesendet wird und wie das zu interpretieren ist. Was hast Du also für ein Problem - außer Du willst Dich irgendwo "einhacken" ?
1,000 : 00 00 00 00 00 00 F0 3F S Exponent Mantisse 0 01111111111 (1)0...0 Ganz gewöhnliches IEEE754 double, little endian.
1 | #include <stdio.h> |
2 | |
3 | int main() |
4 | {
|
5 | const double numbers[] = |
6 | {
|
7 | -10, -5, -4, -3, -2, -1.001, -1.000, -0.999, -0.002, -0.001, 0.000, |
8 | 0.001, 1.000, 1.998, 1.999, 2.000, 3, 4, 5, 10, 33 |
9 | };
|
10 | |
11 | for (int i = 0; i < sizeof numbers / sizeof *numbers; ++i) |
12 | {
|
13 | double n = numbers[i]; |
14 | printf("%f:", n); |
15 | for (int j = 0; j < 8; ++j) |
16 | {
|
17 | printf(" %.02X", ((unsigned char*)&n)[j]); |
18 | }
|
19 | printf("\n"); |
20 | }
|
21 | }
|
Ausgabe auf meinem PC:
1 | -10.000000: 00 00 00 00 00 00 24 C0 |
2 | -5.000000: 00 00 00 00 00 00 14 C0 |
3 | -4.000000: 00 00 00 00 00 00 10 C0 |
4 | -3.000000: 00 00 00 00 00 00 08 C0 |
5 | -2.000000: 00 00 00 00 00 00 00 C0 |
6 | -1.001000: 6A BC 74 93 18 04 F0 BF |
7 | -1.000000: 00 00 00 00 00 00 F0 BF |
8 | -0.999000: 2B 87 16 D9 CE F7 EF BF |
9 | -0.002000: FC A9 F1 D2 4D 62 60 BF |
10 | -0.001000: FC A9 F1 D2 4D 62 50 BF |
11 | 0.000000: 00 00 00 00 00 00 00 00 |
12 | 0.001000: FC A9 F1 D2 4D 62 50 3F |
13 | 1.000000: 00 00 00 00 00 00 F0 3F |
14 | 1.998000: 2B 87 16 D9 CE F7 FF 3F |
15 | 1.999000: 96 43 8B 6C E7 FB FF 3F |
16 | 2.000000: 00 00 00 00 00 00 00 40 |
17 | 3.000000: 00 00 00 00 00 00 08 40 |
18 | 4.000000: 00 00 00 00 00 00 10 40 |
19 | 5.000000: 00 00 00 00 00 00 14 40 |
20 | 10.000000: 00 00 00 00 00 00 24 40 |
21 | 33.000000: 00 00 00 00 00 80 40 40 |
Genereller Tipp für lesbaren Umgang mit little endian Daten: Die Bytes in umgekehrter Reihenfolge notieren, damit die Bits nicht springen. Also das erste Bytes rechts und das letzte links. So wars anno Asbach beim Assembler-Listing der VAX.
Dieter F. schrieb: > Vielleicht bin ich da etwas "zurückgeblieben" - aber Schnittstellen > "vereinbart" man üblicherweise. Also ist genau definiert, was gesendet > wird und wie das zu interpretieren ist. > > Was hast Du also für ein Problem - außer Du willst Dich irgendwo > "einhacken" ? Was genau habt ihr daran nicht verstanden? Habe ich mich falsch ausgedrückt? :-)
Eindeutig IEEE 754 binary64 little endian Hier noch ein Codebeispiel (im Anhang) mit meiner Library: https://github.com/Daniel-Abrecht/IEEE754_binary_encoder/tree/f5ce3e33e62e4120739aa166fa2740e484d95257 Ausgabe:
1 | 00 00 00 00 00 00 24 C0 | -10 |
2 | 00 00 00 00 00 00 14 C0 | -5 |
3 | 00 00 00 00 00 00 10 C0 | -4 |
4 | 00 00 00 00 00 00 08 C0 | -3 |
5 | 00 00 00 00 00 00 00 C0 | -2 |
6 | BC 74 93 6A 18 04 F0 BF | -1.001 |
7 | 00 00 00 00 00 00 F0 BF | -1 |
8 | 87 16 D9 2B CE F7 EF BF | -0.999 |
9 | A9 F1 D2 FC 4D 62 60 BF | -0.002 |
10 | A9 F1 D2 FC 4D 62 50 BF | -0.001 |
11 | 00 00 00 00 00 00 00 00 | 1.11254e-308 |
12 | A9 F1 D2 FC 4D 62 50 3F | 0.001 |
13 | 00 00 00 00 00 00 F0 3F | 1 |
14 | 87 16 D9 2B CE F7 FF 3F | 1.998 |
15 | 43 8B 6C 96 E7 FB FF 3F | 1.999 |
16 | 00 00 00 00 00 00 00 40 | 2 |
17 | 00 00 00 00 00 00 08 40 | 3 |
18 | 00 00 00 00 00 00 10 40 | 4 |
19 | 00 00 00 00 00 00 14 40 | 5 |
20 | 00 00 00 00 00 00 24 40 | 10 |
21 | 00 00 00 00 00 80 40 40 | 33 |
Vielen, vielen Dank an die ganzen Experten hier. Ihr habt mir sehr geholfen. Werde jetzt die Lösungen durcharbeiten. Grüße Martin
Wollte mich nochmal kurz melden und Erfolg melden. Es war schlussendlich sehr einfach, ich konnte die floats (ok, eigentlich wirklich doubles) direkt mit einem kleine C Programm einlesen und die Ausreißer ändern. Hätte ich mal gleich probieren sollen, anstatt mich auf einen Kollegen zu verlassen, der sagte, die kommen von einem Mikrokontroller und sind irgendwie anders... Endlich habe ich eine Möglichkeit, die falschen Statistikwerte zu korrigieren. Warum man hier wegen einer solchen Frage soviel Ironie und Verdächtigungen über sich ergehen lassen muss, wird sich wohl nur den Schreiberlingen erschließen. An alle anderen: Danke nochmal. Grüße Martin
Martin U. schrieb: > Endlich habe ich eine Möglichkeit, die falschen Statistikwerte zu > korrigieren. Aha, also Statistiken manipulieren.
Datenblattfinder schrieb: > Aha, also Statistiken manipulieren. Denen man dann wieder vertrauen kann!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.