これはエンディアンの問題のようですが、プレーンバニラビッグエンディアン対リトルエンディアンの問題ではありません。 ARMは時々、double
のために通常とは異なるバイト順序を使用します。ジャン・ミシェル・ミューラーによって、ら「浮動小数点演算のハンドブック」:
から... -7.0868766365730135 x 10^-268
に最も近い倍精度数は、メモリ内のバイト 11 22 33 44 55 66 77 88
の配列によりコードされます(最高 1の低い方から)のx86およびLinux/IA-64プラットフォーム(それらは リトルエンディアンであると言われている)で、ほとんどのPowerPCプラットフォームで88 77 66 55 44 33 22 11
によって、(それらはビッグエンディアンであると言われています)。 IA-64、ARM、およびPowerPCのような などのアーキテクチャは、バイエンディアンと言われています。すなわち、 は、 の設定に応じて、リトルエンディアンまたはビッグエンディアンのいずれかになります。
ARMベースのプラットフォームの一部が例外です。伝統的浮動小数点アクセラレータ(FPA)倍精度数は、ビッグエンディアン順に 2つの32ビットワードに分解し、機械の エンディアンに応じて格納されている アーキテクチャを使用している ARMプロセッサすなわちリトルエンディアンであり、これは を意味し、上記の数は配列55 66 77 88 11 22 33 44
によってコードされる。 ARMは最近浮動小数点 算術用の新しいアーキテクチャを導入しました。ベクトル浮動小数点(VFP)です。この場合、ワードはプロセッサのネイティブバイトオーダーで に格納されます。
M_PI
がどのように見える表現があります、ビッグエンディアンバイト順に見て:
:
0x400921fb54442d18
を8.6192e+97
により近似数が多いように見える表現を持つウィル
0x54442d18400921fb
よく見ると、2つの32ビットワードは入れ替えられますが、32ビットワード内のバイトオーダーは同じです。つまり、ARMの伝統的なダブルポイント形式は、Qtライブラリを混乱させるようです(またはQtライブラリが誤って構成されています)。
プロセッサが従来の形式を使用していて、QtがVFP形式であることが予想されるかどうか、あるいは逆の場合は分かりません。しかし、それはその2つの状況の1つと考えられます。
この問題を解決する方法も正確にはわかりません。これを正しく処理するために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("");
平野リトルエンディアンのマシンが表示されます。
次のスニペットは、少なくともあなたはQtの中で変更する必要があるもの絞り込む役立つ可能性がある、コンパイラが使用しているdouble
のためのどのような形式を教えてくれます。
11 22 33 44 55 66 77 88
もう少し分析とアップデート:
現時点では、実際のデバッグを行うことができません(現時点で私のワークステーションにアクセスすることさえできません)。http://qt.gitorious.orgで入手可能なQtソースを見てください。
Qtがqlocale.cppのQLocalePrivate::doubleToString()
関数を呼び出して、double
を英数字形式に変換するようです。
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表現を使用しているプラットフォーム(全体のシステムがリトルエンディアンであるかどうかにかかわらず、double
の32ビットの半分がビッグエンディアンの順序で格納されていると仮定します) QT_QLOCALE_USES_FCVT
を定義してQtをビルドする必要があります。 Qtをビルドするときは、configureスクリプトに-DQT_QLOCALE_USES_FCVT
オプションを渡すだけです。
Qt内で起こっているように思われることについて、私が考えていることと一緒に考えてみましょう。 –
よく研究されています。 +1 –
詳細な対応をありがとうございます!実際問題は '-DQT_QLOCALE_USES_FCVT'オプションがないことでした。再構築後、すべてが正しく機能しました。スニペットを再構築する前に、次の行を印刷しました: '55 66 77 88 11 22 33 44'。 –