4

私は小さな LLVM ベースのプログラミング言語の数学関数を書いていますが、現在、一般的な丸め関数 floor、ceil、round (to even) を実装する方法に困惑しています。1 つ目は、これらの関数のアルゴリズムの説明が見つからなかったためです。2 つ目は、LLVM が持つ機能に精通していないためです。丸めます。

負の数を正しく丸めることができることは必須ですが、特定の精度への丸めはそうではありません。整数値への丸めで十分です。LLVM ビットコードから使用できる既存の実装を指すだけでも機能します。

4

3 に答える 3

2

LLVM言語リファレンスマニュアルから始めたいと思うでしょう。

これらの線に沿って何かのように実装することから始めるかもしれませんtrunc( )(警告、実際にはこれを使用しないでください。これは例として意図されており、正しくありません。以下の説明を参照してください)。

define float @trunc(float %x) {
    %rounded = fptosi float %x to i32
    %asFloat = sitofp i32 %rounded to float
    ret float %asFloat
}

このfptosi ... to ...命令は、浮動小数点値をゼロに丸める丸めモードに従って整数値に丸めることとして文書化されています。このsitofp ... to ...命令は、その値を浮動小数点値に変換して返します。

ただし、この実装には問題があります。私がリンクした言語リファレンスを読んで、「fptosi ... to ...最も近い整数への丸めの結果が宛先タイプに適合しない場合、の動作は未定義です。」

ただし、十分に大きい浮動小数点数はすべてすでに整数であり、丸める必要がないため、これは非常に簡単に回避できます。の絶対値がx2^23以上の場合は、x自体を返すことができます。

(これはすべて単精度の場合です。倍精度の場合は、を使用する可能性が高くi64、2 ^ 52のしきい値を使用する必要があります)

floorおよびのような他の操作については、roundから始めてtrunc、残差を確認し、それx - trunc(x)に応じて結果を調整することができます。

または、これらの関数がすでに含まれているホストプラットフォームのCライブラリを呼び出すこともできます。これは、多くのプログラミング言語で採用されているアプローチです。

于 2010-08-24T22:29:44.277 に答える
1

Google Code Search を見ると、いくつかの結果があります。リンクされた例では、IEEE 浮動小数点数を想定しています。floor通常、一般的な PC 用のコンパイラは、浮動小数点命令にコンパイルするだけです。たとえば、元の 387 算術プロセッサには、FPREM多かれ少なかれ必要なものの一部を実行する命令がありますfloor

于 2010-08-18T03:51:51.663 に答える
1

float ベクトルのフロアを次の方法で実装しました。値 x を「切り捨て」、次に x と trunc(x) を比較します。trunc(x)>x の場合、floor(x) は常に最大で x でなければならないため、1 を引きます。これをHaskellでコーディングしました。これが役立つかどうかはわかりません。http://code.haskell.org/~thielema/llvm-extra/src/LLVM/Extra/Vector.hsの floorLogical を参照して ください。

偶数への丸めは一般にコストが高く、あまり役に立ちません。私は単純に floor(x+0.5) を使用します。SSE4.1にはroundss、roundpsなどもあります。

于 2012-05-23T20:18:44.197 に答える