文字列から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ビットに収まる数値の浮動小数点数および任意のサイズの二重リテラルは常に正しく表現されます。倍精度から単精度に切り上げることで、私はを二重に再現することもできます丸め誤差があります。

2
追加された 編集された
ビュー: 1
あなたの心/文脈の中の「C浮動小数点数」とは何ですか?
追加された 著者 Kerrek SB,
編集を参照してください。 Cコードで浮動小数点リテラルの数値を取得する必要があります。解析は実際にレジスタの長さに依存しません。
追加された 著者 ralf,
質問が更新されました。単精度浮動小数点数を正しく取得する場合でも、64ビットより大きい値のリテラルを解析する必要があります。
追加された 著者 ralf,
Nitpickerのコーナー:実際には、いくつかのプラットフォームでは long double は128ビットです。 x86では通常80ビット(x87 FPUの内部精度)であり、VC ++では通常の double詳細</​​a>)。
追加された 著者 Matteo Italia,
私は数字を解析することが何を意味するかを完全には分かっていません。数値定数が整形式であることを確認したいだけですか?または、数値に変換しますか?次に、表現問題と解析問題があります。
追加された 著者 Jeffrey Scofield,
OCamlの浮動小数点型は64ビットなので、float_of_string関数はCの浮動小数点型とdouble型のどちらでも問題なく動作します。関数 float_to_string は単精度浮動小数点数に対しては not しません。 blog.frama-c.com/index.php?post 2010/10/11/20/ &hellip;
追加された 著者 Pascal Cuoq,
また、 strtod()strtof()(前者はOCamlで使用されていました。これらの数値には二重丸め誤差を示すものがあります。私は最近同じ問題を解決していますが、 long double をしなかったので、私のソリューションに興味を持っているかどうかはわかりません。さらに、Big_int/Zarithの上にある共通のインターフェースレイヤーを持つFrama-Cにあります。
追加された 著者 Pascal Cuoq,

2 答え

I wrote my answer in the form of a blog post

OCamlの strtold()strtof()をインターフェースすることができます。前者の場合、ホスト上で long doubledouble より大きい場合にのみポイントが生成されるため、どのように結果を格納するのかを考慮する必要があります建築。これらの関数は、最も広く使われているCライブラリの一つにバグがあるという問題が残っています。非常にわずかにバギーですが、二重丸めを勉強するためにこれをやっているのであれば、まさにこの例題のためにバグがあります。

別の方法は、から独自の関数を書くことですあなたが参照するブログに投稿してください。

最後に、「単精度浮動小数点数を取得する場合でも、64ビットより大きい値を持つリテラルを解析する必要があります」という句は、コメントに使用するのがまだ変な方法です。単精度浮動小数点数を単精度に丸める前に単精度浮動小数点の表現を解析できる中間形式は、無損失である必要があります。そうでなければ、二重丸めが行われます。ロッシー中間フォーマットの精度によってはダブルラウンディングが多少難しいかもしれませんが、80ビットまたは128ビットのバイナリ浮動小数点フォーマットを使用しても問題は解決されません。私が推奨する単純なアルゴリズムでは、中間形式は2つの多重精度整数の一部です。

2
追加された

私はこの質問の質問が表示されません:)

"C float literal"のocamlパーサーが必要であると答えた場合、答えは - あなた自身で書いてください。それはあまり難しくなく、実装の詳細と "C float literal"が実際に意味するものを厳密に制御します。

0
追加された
あなたは正しい、本当にもう質問はありません。私はパーサを自分で書くより簡単な方法があると思った。
追加された 著者 ralf,
私はあなたの仕事がかなり具体的であるため、そうではないと思います。
追加された 著者 ygrek,