4

float を使用する C のアルゴリズムを実装しています。i386 でコンパイルして実行すると、armel でコンパイルして実行したときとは異なる結果が得られます。特に float による int の除算では、別の float になります。

この問題を示すために、アルゴリズムからいくつかのコードを抽出しました。

#include <stdio.h>
void main(void)
{
    float x = 4.80000019;
    float y = 4.80000019;
    int a = 38000;
    int b = 10000;
    int result = (a/x)+(b/y);
    printf("%.8f, %.8f\n", x, y); // same on i386 and armel
    printf("%f, %f\n", a/x, b/y); // slightly different on each
    printf("%d\n", result);       // prints 9999 on i386, and 10000 on armel
}

2 つのプラットフォームが異なる結果を生成する理由を誰か説明できますか?

アレックス

4

3 に答える 3

6

「過剰精度」を参照してください。最新の x86 でこれを抑制するには、-msse2 -mfpmath=sse.

于 2013-02-07T15:08:02.877 に答える
4

現在アームでテストすることはできませんが、i386 と amd64 でも結果が異なります - 同じ CPU 上ですが、-m32 フラグでコンパイルされています。これは内部 FPU 構造のためです。i387 は 80 ビット浮動小数点レジスタを使用して操作を実行し、結果を 32 ビット浮動小数点に縮小します (要求された場合)。amd64 命令セットでは、代わりに SSE が使用されますが、これには正確なレジスタがありません (ただし、少なくとも 32 ビットです)。ARMにも少なくとも32ビットがあると思いますが、これを超えるものは保証されていません.

于 2013-02-07T11:35:05.313 に答える
2

C 標準では、実装する必要のあるものの数は規定されておらず、実装固有の動作が許可されています。浮動小数点演算は、さまざまな実装、したがってさまざまな結果が完全に問題ない領域の 1 つです。あなたはそれを受け入れるか、回避策を構築します。

于 2013-02-07T11:45:26.687 に答える