Ich habe Qt 4.4.3 für ARMv5TE gebaut. Ich versuche ein double
in ein QString
zu konvertieren:
aber seltsame Ausgabe:
%Vor%Wie bekomme ich die richtige Zeichenfolge?
Dies scheint eine Art Endianess-Problem zu sein, aber nicht Ihr einfaches Van-Big-Endian-gegen-Little-Endian-Problem. ARM verwendet manchmal eine ungewöhnliche Byte-Reihenfolge für double
. Aus "Handbook of Floating-Point Arithmetic" von Jean-Michel Muller, et al .:
... die Nummer mit der doppelten Genauigkeit, die am nächsten ist
-7.0868766365730135 x 10^-268
wird durch die Bytefolge codiert11 22 33 44 55 66 77 88
im Speicher (von der niedrigsten zur höchsten ein) auf x86 und Linux / IA-64 Plattformen (sie sollen sein little-endian ) und von88 77 66 55 44 33 22 11
auf den meisten PowerPC-Plattformen (sie werden als big-endian bezeichnet). Einige Architekturen, wie z als IA-64, ARM und PowerPC wird gesagt, bi-endian zu sein. d.h. sie können sei entweder Little-Endian oder Big-Endian abhängig von ihren Konfiguration.Es gibt eine Ausnahme: einige ARM-basierte Plattformen. ARM-Prozessoren habe traditionell den Fließkomma-Beschleuniger (FPA) verwendet Architektur, wo die Zahlen mit doppelter Genauigkeit zerlegt werden zwei 32-Bit-Wörter in der Big-Endian-Reihenfolge und gespeichert nach der Endlichkeit der Maschine, d. h. Little-Endian im Allgemeinen, was bedeutet dass die obige Zahl durch die Sequenz
55 66 77 88 11 22 33 44
codiert ist. ARM hat vor kurzem eine neue Architektur für Gleitkomma eingeführt arithmetisch: Vektor Gleitkomma (VFP), wo die Wörter gespeichert werden in der nativen Byte-Reihenfolge des Prozessors.
Wenn in einer Big-Endian-Byte-Reihenfolge betrachtet wird, hat M_PI
eine Repräsentation, die wie folgt aussieht:
Die große Anzahl von 8.6192e+97
wil hat eine Repräsentation, die wie folgt aussieht:
Wenn Sie genau hinsehen, werden die zwei 32-Bit-Wörter vertauscht, aber die Byte-Reihenfolge innerhalb der 32-Bit-Wörter ist die gleiche. Offensichtlich scheint das "traditionelle" Doppelpunktformat von ARM die Qt-Bibliothek zu verwirren (oder die Qt-Bibliothek ist falsch konfiguriert).
Ich bin mir nicht sicher, ob der Prozessor das traditionelle Format verwendet und Qt erwartet, dass es im VFP-Format vorliegt, oder wenn die Dinge umgekehrt sind. Aber es scheint eine dieser beiden Situationen zu sein.
Ich bin mir auch nicht sicher, wie ich das Problem genau beheben kann - ich denke, es gibt eine Möglichkeit, Qt so zu bauen, dass es korrekt funktioniert.
Das folgende Snippet wird Ihnen zumindest sagen, welches Format für double
der Compiler verwendet, was Ihnen helfen kann einzugrenzen, was in Qt geändert werden muss:
Ein einfacher Little-Endian-Rechner zeigt Folgendes an:
%Vor%Update mit ein bisschen mehr Analyse:
Im Moment kann ich kein echtes Debugging durchführen (ich habe im Moment noch nicht einmal Zugriff auf meine Workstation), aber ich schaue mir die Qt-Quelle an, die auf Ссылка hier ist eine zusätzliche Analyse:
Es sieht so aus, als ob Qt die Funktion QLocalePrivate::doubleToString()
in qlocale.cpp aufruft, um eine double
in eine alphanumerische Form zu konvertieren.
Wenn Qt mit QT_QLOCALE_USES_FCVT
definiert ist, verwendet QLocalePrivate::doubleToString()
die Funktion fcvt()
der Plattform, um die Konvertierung durchzuführen. Wenn QT_QLOCALE_USES_FCVT
nicht definiert ist, endet QLocalePrivate::doubleToString()
mit dem Aufruf von _qdtoa()
, um die Konvertierung durchzuführen. Diese Funktion untersucht die verschiedenen Felder von double
direkt und scheint davon auszugehen, dass double
in einer strikten Big-Endian- oder Little-Endian-Form vorliegt (z. B. mit den Funktionen getWord0()
und getWord1()
) niedriger und hoher Wert von double
).
Siehe Ссылка und Ссылка oder Ihre eigene Kopie der Dateien für Details.
Angenommen, Ihre Plattform verwendet die traditionelle ARM FPA-Repräsentation für double
(wobei die 32-Bit-Hälften von double
in Big-Endian-Reihenfolge gespeichert sind, unabhängig davon, ob das Gesamtsystem Little-Endian ist), I Ich denke, du musst Qt mit der QT_QLOCALE_USES_FCVT
definieren. Ich glaube, dass Sie nur die Option -DQT_QLOCALE_USES_FCVT
an das configure-Skript übergeben müssen, wenn Sie Qt erstellen.
Derselbe Code erzeugt eine korrekte Ausgabe auf einem x86-Computer (unter Windows XP) mit Qt 4.7.0.
Ich sehe die folgenden Möglichkeiten für die Ursache des Problems:
Ich fand diesen Forenbeitrag bei einem ähnlichen Problem, das davon ausgeht, dass es sich um ein Konvertierungsproblem für große / kleine Endiane handeln könnte.
Ich kann nicht sagen, wie ich das beheben kann, da ich überhaupt nicht mit ARM vertraut bin, aber vielleicht hilft Ihnen diese Information trotzdem.