Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hallo,
ich habe einen Hexadezimalstring eines Doubles.
Z.B.:
Code:
9B690C84AE8EB93F
Jetzt möchte ich diesen in einen Double-Wert umwandeln. Die einzelnen HexZahlen sind dabei die Bytes des Doubles.
Jemand ne Ahnung wie das geht? Ich bin mit meinem gerade anfangendem Latein auch schonwieder am Ende...
Hallo, ich hab jetzt lange probiert, und auch ein extra Testprogramm gemacht. Irgendwas klappt da nicht...
Code:
String t = "0x000000000000F03F"; // ist 1.0
g.drawString(t, 5, 30);
long h = Long.decode(t);
g.drawString(Long.toString(h), 5, 40);
double m = Double.longBitsToDouble(h);
g.drawString(Double.toString(m), 5, 50);
Bei der Ausgabe kommt dann sowas raus:
Code:
0x000000000000F03F
61503
3.03865E-319
Ich weis nicht was ich falsch gemacht habe, aber so funktioniert es nicht. Ich habe den Doublewert mehrfach geprüft, er ist 1.0 wenn man ihn richtig "übersetzt".
Ich bin mir nicht hundert-prozentig sicher ob das "0x" davor stimmt, aber wenn ich das nicht hinschreibe, dann macht er einen Fehler, weil er wenn das erste Zeichen eine Null ist, die selbige weglässt.
Demnach Vorzeichen 0 = plus
Exponent 0 = 0, also 0 - 1023 = 2^(-1023), bzw. hier (da alle 0) "smallest subnormal" (also ohne hidden Bit), also 2^(-1075) = 2.5 x 10^(-324)
Mantisse 1111000000111111. Hat 16 Stellen, also irgendein Wert so grob um 2^(-1056) herum, also etwas um 1.3 x 10^(-318). Das Ergebnis scheint also durchaus korrekt zu sein.
Also "wert = (+)Mantisse * 10^(-318)"
Suche für das Double-Format mal nach "IEEE Floating Point Standard"
Ok, kopfsalat, das verwirrt mich jetzt schon ein kleines bisschen.
Aber von dem Teil, den ich meine verstanden zu haben kann ich sagen:
Ich hab den Double einfach von Delphi in eine Datei schreiben lassen (Double is ja überall gleich nach IEEE). Und dann hab ichs mir im HexEditor angeschaut. Dabei kam dieser HexString halt für 1.0 raus. Der HexEditor hat auch eine Funktion wo man acht markierte Bytes als Double anzeigen kann, und der meinte ebenfalls, es wäre 1.0!
Also müsste der doch theoretisch stimmen.
Und was bringt es mir jetzt nach dem Standard zu suchen, also dann nen eigenen Parser oso zu schreiben schaff ich net, auch wenn ich dann weis wie ein double aufgebaut ist.
Edit:
Ich hab das gerade mal nachgeschaut zu meintest:
D.h. deine Bits als HexString entsprechen meinem "000000000000F03F".
Edit2:
Achso, hm du scheinst das auf die verschiedenen Bits von double und long zu beziehen und, dass die dann einfach so übertragen werden. Also liegt das Problem darin, dass der long das 0xF03F als Zahl betrachtet und nicht das 000000000000F03F als String aus dem er seine einzelnen Bits auslesen soll.
Ajo! Gut, dass dir das noch aufgefallen ist!
Dann liegt hier eine Ausuferung des "Big Endian" <-> "Little Endian" Problems vor:
Was das ist ? Siehe dazu hier:
Diese blöde Unstandardisiertheit schlägt in den blödesten Situationen zurück. Da kannst Du nichts gegen machen, als entweder die Zahlen von vorneherein gleichartig zu speichern, oder aber die Bytes zunächst neu zusammenzusetzen, z.B. so:
Code:
class BigLittleEndian
{
public static void main (String [] args)
{
Long val = Long.parseLong("1122334455667788", 16);
System.out.println("Big Endian : " + Long.toHexString(val));
val = Long.reverseBytes(val);
System.out.println("Little Endian : " + Long.toHexString(val));
}
}
Hm und wo is jetzt das Problem. Auch wenn die Bits verkehrtrum wären is doch trotzdem das Problem, dass er den HexString als Zahl und nicht als Bitwerte für den long sieht...
[schild=2 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]Hmpf![/schild]
Hm und wo is jetzt das Problem. Auch wenn die Bits verkehrtrum wären is doch trotzdem das Problem, dass er den HexString als Zahl und nicht als Bitwerte für den long sieht...
???
Sobald der HexString als Zahl gesehen wird, sind es doch gleich Bitwerte für einen Long. Jede Zahl wird doch in Bits gespeichert, nur für die Anzeige kann man die schön in Dezimal oder Hexadezimal, etc. anzeigen lassen.
Wahrscheinlich speichert Dein Delphi-Programm im Little-Endian-Format, d.h. ein 8-Byte-Wert (ob Long, oder Double ist wurscht) der Form "0x1122334455667788") wird in die Datei geschrieben als 88 77 66 55 44 33 22 11. Deswegen wird aus 1.0, was in Hex-Repräsentation heißt : 0x3FF0000000000000, gespeichert als 00 00 00 00 00 00 F0 3F. Dein Hex-Viewer wird das wohl als Little-Endian-Double interpretiert gleich entsprechend umrechnen.
Die IEEE-Norm legt nicht fest, ob Little- oder Big-Endian genutzt werden soll.
Du musst, solltest Du also die 8 Bytes in der Reihenfolge einlesen, die wieder umdrehen, dazu gibt es die reverseBytes - Methode.
Du liest also die Zahl wie in deinem eigenen Beispiel ein, wandelst sie in einen long mit "long h = Long.decode(t);" Direkt danach rufst Du "h = Long.reverseBytes(h);" auf, um die 8 Bytes umzudrehen, um dann mit "double m = Double.longBitsToDouble(h);" dieselben Bits als double-Wert zu interpretieren.