質問: 文字列からlong doubleを解析する OCamlを使用してCコードで浮動小数点リテラルを解析する必要があります。 OCamlのfloat型は64ビットです。私はリテラルの文字列、64ビットに丸められた数値、その種類(float、double、またはlong double)を持っています。 問題は64ビットより大きい数値のリテラルです: 1. 長い二重リテラル 2. 接尾辞を持たない場合に二重丸め誤差が発生する「f」接尾辞付きの浮動小数点数リテラル。 OCamlの任意精度モジュールは文字列から有理数を解析できます「123/123」のように表示されますが、「123.123」、「123e123」、「0x1.23p-1」には表示されません。 背景:私は、 CIL を使用してCプログラムの価値分析を行っています。 64ビットに収まる数値の浮動小数点数および任意のサイズの二重リテラルは常に正しく表現されます。倍精度から単精度に切り上げることで、私はを二重に再現することもできます丸め誤差があります。
回答: I wrote my answer in the form of a blog post OCamlの `strtold()`と `strtof()`をインターフェースすることができます。前者の場合、ホスト上で `long double` が `double` より大きい場合にのみポイントが生成されるため、どのように結果を格納するのかを考慮する必要があります建築。これらの関数は、最も広く使われているCライブラリの一つにバグがあるという問題が残っています。非常にわずかにバギーですが、二重丸めを勉強するためにこれをやっているのであれば、まさにこの例題のためにバグがあります。 別の方法は、から独自の関数を書くことですあなたが参照するブログに投稿してください。 最後に、「単精度浮動小数点数を取得する場合でも、64ビットより大きい値を持つリテラルを解析する必要があります」という句は、コメントに使用するのがまだ変な方法です。単精度浮動小数点数を単精度に丸める前に単精度浮動小数点の表現を解析できる中間形式は、無損失である必要があります。そうでなければ、二重丸めが行われます。ロッシー中間フォーマットの精度によってはダブルラウンディングが多少難しいかもしれませんが、80ビットまたは128ビットのバイナリ浮動小数点フォーマットを使用しても問題は解決されません。私が推奨する単純なアルゴリズムでは、中間形式は2つの多重精度整数の一部です。