0


0

SIGILLを浮動小数点から固定変換に取得する

次のコードを実行した後、SIGILLを受け取りました。 私はそれが何が悪いのか本当に理解できません。

ターゲットプラットフォームはARMであり、既知のライブラリ(このコードが含まれているライブラリ)を移植しようとしています。

void convertFloatToFixed(float nX, float nY, unsigned int &nFixed) {
    short sx = (short) (nX * 32);
    short sy = (short) (nY * 32);

    unsigned short *ux = (unsigned short*) &sx;
    unsigned short *uy = (unsigned short*) &sy;

    nFixed = (*ux << 16) | *uy;
}

それに関するどんな助けも大歓迎です。

前もって感謝します

1 Answer


1


一部のARMプロセッサにはハードウェア浮動小数点があるものとないものがあるため、この関数はハードウェア浮動小数点用にコンパイルされている可能性がありますが、プラットフォームに浮動小数点ユニットがないため、浮動小数点命令によりプロセッサがレポートする可能性があります違法な指示。 これがテストプログラムの最初の浮動小数点計算である場合、それが問題である可能性が非常に高くなります。 プラットフォームのドキュメントを確認して、gccに渡す必要がある-marchオプションを見つけるか、すでに動作しているプログラムで使用されるコンパイルオプションを調べます。

この関数には動作が定義されていないため、目的の動作が何であるかを示すことなく、改善を提案することは困難です。 始めにこのようなものを試してください:-

void convertFloatToFixed(float nX, float nY, unsigned int &nFixed) {
    assert(nX * 32 < INT_MAX);
    assert(nY * 32 < INT_MAX);

    int sx = nX * 32;
    int sy = nY * 32;

    unsigned int ux = sx;
    unsigned int uy = sy;

    nFixed = (ux << 16) | uy;
}

(他の人が指摘したように)厳密なエイリアス規則を破るポインターキャストを取り除きました。 また、「short」の代わりに「int」を使用しました。 とにかく計算の前に int`に拡張されるので、一般に short`自動変数を持つことは意味がありません。 (16ビットずつ「short」をシフトするのはあまり役に立たないので、良い仕事です。)デバッグビルドがfloatから整数への変換がオーバーフローするかどうかを確認できるようにチェックを追加しました。未定義の動作。