4

ご存知のように、IEEE浮動小数点数は、数値が浮動小数点の範囲内にある限り、すべての整数と、1/2や3/4などの2の累乗の整数倍の正確な表現を格納できます。ポイントタイプ。

ただし、浮動小数点パーサーは通常、そのような数値の10進表現を解析した正確な結果を保証しますか?

たとえば、Cプログラムでリテラル0.75として使用する場合double、コンパイラは、コンパイルされたコードに3/4の正確な表現が含まれていることを保証しますか、それとも、0.7の不正確な表現といくつかの不正確な表現の合計を生成するリスクがありますか? 0.05の不正確な表現?

または、同様に3e4、リテラルとして使用する場合double、正確な3に2 ^(4 * ln(10)/ ln(2))の不正確な表現または同様の数学を掛けることができますか?

この問題でFPパーサーが一般的に従う必要のある標準はありますか、それとも一般的に完全に実装に任されていますか?後者の場合、GCCやglibcのような実際に重要な実装が実際にどのように機能するかを知っている人はいますか?

私は主に好奇心を求めているだけであり、行動に依存したいからではありません。ただし、値が文字通りのソースからのみ取得されていることがわかっている場合は、FPの等価性の比較が機能することが保証されていることを知っておくと非常に便利な場合があります。

4

2 に答える 2

4

C標準では、浮動小数点定数を、リテラル定数の正確な値に最も近い表現可能な値、またはC 2011 6.4.4.2に従って、最も近い値に直接隣接するより大きなまたはより小さな表現可能な値にすることができます。より良い。変換を正しく行うためのアルゴリズムが公開されているため、最新の実装の方がうまくいくはずです。

ただし、C標準では、16進浮動小数点定数も提供されているため、コンパイラーは変換を正しく行うことが容易になります。16進浮動小数点定数の基本形式は、0xhhhです。hhh p eee、ここで、hhhは16進数で、eeeは10進数の指数であり、符号が付いている場合があります。(「。」の片側の16進数は、ゼロの場合は省略できます。右側の数字を省略した場合は、ピリオドを省略できます。)指数は2の累乗です。

C標準では、浮動小数点数の基数がC実装で2の累乗である場合、16進数の浮動小数点定数を正しく丸める必要があります。16進定数を正確に表すことができない場合は、診断メッセージを生成することをお勧めします。

たとえば0x3p-2正確に.75である必要があります。

于 2013-01-15T13:00:07.650 に答える
2

通常、抽象構文ツリーで、ソースコードの小数表現に最も近い浮動小数点数を取得する保証はありません。C99などの言語標準では、1つのULP内(つまり、最も近いものではなく、最も近い2つのうちの1つ)内にある必要があると指定されている場合があります。実際には、コンパイラーはホストの、、…関数を使用する場合がありますがstrtof()strtod()これも最も近い数値を返すように指定されておらず、実際にはそうでない場合もあります)。

1つのULP内制約は、浮動小数点数の正確な10進表現をその数に変換する必要があることを意味します。ただし、RubyやTclなどの多くのインタープリターには、ホストにインタープリターがない場合に備えて、独自のインタープリターが付属しています。 strtod()その実装はひどいものであり、いくつかのULPによって間違った結果を返す可能性があります。

独自の変換関数を実装してこれを解決する必要がある場合は、大きな整数に基づく単純ですが正しい関数の概要は、ExploringBinaryブログにあります。


要約すると、1つのULP内への10進数から浮動小数点への変換を指定する言語の場合、高品質のコンパイラ実装を使用している限り、正確な表現に問題はありません。そのような仕様のないインタプリタ言語の場合、ホストstrtod()が呼び出されて問題が発生するか、恐ろしい実装が使用されます。この場合はそうではありません。

于 2013-01-15T06:04:23.203 に答える