これは一種のエンディアンの問題のように見えますが、単純なバニラのビッグエンディアンとリトルエンディアンの問題ではありません。ARM は、double
. Jean-Michel Muller ほかによる「Handbook of Floating-Point Arithmetic」より:
... に最も近い倍精度数は
、x86 および Linux/IA-64 プラットフォーム (リトル エンディアンと呼ばれる)では、メモリ内のバイト シーケンス (最小から最大)
-7.0868766365730135 x 10^-268
によってエンコードされます
。ほとんどのPowerPC プラットフォームで (ビッグエンディアンと言われています)。IA-64、ARM、PowerPC などの一部のアーキテクチャは、バイエンディアンと言われています。つまり、構成に応じて、リトル エンディアンまたはビッグ エンディアンのいずれかになります。11 22 33 44 55 66 77 88
88 77 66 55 44 33 22 11
例外があります: 一部の ARM ベースのプラットフォームです。ARM プロセッサは従来、浮動小数点アクセラレータ(FPA) アーキテクチャを使用してきました。このアーキテクチャでは、倍精度数がビッグ エンディアンの順序で 2 つの 32 ビット ワードに分解され、マシンのエンディアン (リトルエンディアン) に従って格納されます。一般に、これは上記の数値がシーケンスによってエンコードされることを意味します55 66 77 88 11 22 33
44
。ARM は最近、浮動小数点演算用の新しいアーキテクチャであるベクトル浮動小数点(VFP) を導入しました。このアーキテクチャでは、ワードはプロセッサのネイティブ バイト オーダーで格納されます。
ビッグ エンディアンのバイト順でM_PI
見ると、次のような表現になります。
0x400921fb54442d18
wilによって近似された大きな数8.6192e+97
は、次のように表現されます。
0x54442d18400921fb
よく見ると、2 つの 32 ビット ワードが入れ替わっていますが、32 ビット ワード内のバイト順は同じです。どうやら、ARM の「伝統的な」ダブルポイント形式は Qt ライブラリを混乱させているようです (または Qt ライブラリの設定が間違っています)。
プロセッサが従来の形式を使用しており、Qt が VFP 形式であることを期待しているのか、それとも逆なのかはわかりません。しかし、それはこれら2つの状況のいずれかのようです。
また、問題を修正する方法も正確にはわかりません.Qtを構築してこれを正しく処理するためのオプションがあると思います.
次のスニペットは、少なくともdouble
コンパイラが使用している形式を示します。これは、Qt で変更する必要があるものを絞り込むのに役立つ場合があります。
unsigned char* b;
unsigned char* e;
double x = -7.0868766365730135e-268;
b = (unsigned char*) &x;
e = b + sizeof(x);
for (; b != e; ++b) {
printf( "%02x ", *b);
}
puts("");
普通のリトル エンディアン マシンでは次のように表示されます。
11 22 33 44 55 66 77 88
もう少し分析して更新します。
現時点では、これを実際にデバッグすることはできません (現在、ワークステーションにアクセスすることさえできません) が、 http: //qt.gitorious.orgで入手できる Qt ソースを見ると追加の分析:
Qt がQLocalePrivate::doubleToString()
qlocale.cpp の関数を呼び出して adouble
を英数字形式に変換しているようです。
Qt がQT_QLOCALE_USES_FCVT
定義済みでコンパイルされているQLocalePrivate::doubleToString()
場合、プラットフォームのfcvt()
関数を使用して変換を実行します。が定義されていない場合QT_QLOCALE_USES_FCVT
は、変換を実行するために呼び出されます。この関数は のさまざまなフィールドを直接調べ、が厳密なビッグ エンディアンまたはリトル エンディアン形式であると想定しているように見えます (たとえば、関数と関数を使用してそれぞれの下位ワードと上位ワードを取得します)。QLocalePrivate::doubleToString()
_qdtoa()
double
double
getWord0()
getWord1()
double
http://qt.gitorious.org/qt/qt/blobs/HEAD/src/corelib/tools/qlocale.cppおよびhttp://qt.gitorious.org/qt/qt/blobs/HEAD/src/corelibを参照してください。詳細については、/tools/ qlocale_tools.cppまたは独自のファイルのコピーを参照してください。
double
プラットフォームが従来の ARM FPA 表現(システム全体がリトル エンディアンであるかどうかに関係なく、32 ビットの半分がビッグ エンディアンの順序で格納される) を使用していると仮定すると、double
Qt をビルドする必要があると思います。QT_QLOCALE_USES_FCVT
定義されています。-DQT_QLOCALE_USES_FCVT
Qt をビルドするときに configure スクリプトにオプションを渡すだけでよいと思います。