3

私のクライアント アプリケーションは、writeln と readln を使用して、テキスト ファイルを介して real 型のかなりの数の変数をエクスポートおよびインポートします。コードが次のようになるように、書き込まれたフィールドの幅を広げようとしました。

writeln(file, exportRealvalue:30); //using excess width of field
....
readln(file, importRealvalue);

エクスポートしてから再度インポートしてエクスポートし、ファイルを比較すると、最後の 2 桁に違いがあります。

-1.23456789012E-0002
-1.23456789034E-0002

これは実際にアプリに違いをもたらすため、クライアントは私がそれについて何ができるかを知りたがっています. 今、それを行うのが書き込み/読み取りだけであるかどうかはわかりませんが、ヘイスタックに再び飛び込む前に、簡単な質問を投げかけようと思いました。これでバイナリにする必要がありますか?

これは通貨などを扱うアプリではありません。ファイルとの間で値を読み書きするだけです。浮動小数点が時々少し奇妙であることは知っていますが、ルーチンの 1 つ (writeln/readln) で面白いことが起こっているのではないかと思いました。

4

6 に答える 6

7

精度を高めるために拡張に切り替えてみてください。ただし、指摘したように、浮動小数点数の有効桁数は非常に多いため、正確に格納されている桁数よりも多くの桁数を表示することができ、指定した動作が発生する可能性があります。

Delphi ヘルプから:

基本的な Win32 の実数型

                                            | | 重要 | サイズイン
タイプ | 範囲 | 数字 | バイト
------+-------------------------------------------------+----- ------+----------
リアル | -5.0 x 10^–324 .. 1.7 x 10^308 | 15–16 | 8  
リアル48 | -2.9 x 10^–39 .. 1.7 x 10^38 | 11-12 | 6   
シングル | -1.5 x 10^–45 .. 3.4 x 10^38 | 7-8 | 4   
ダブル | -5.0 x 10^–324 .. 1.7 x 10^308 | 15-16 | 8   
拡張 | -3.6 x 10^–4951 .. 1.1 x 10^4932 | 10-20 | 10   
コンプ | -2^63+1 .. 2^63–1 | 10-20 | 8   
通貨 | -922337203685477.5808.. | | |
                    922337203685477.5807 | 10-20 | 8   

: 6 バイトのReal48型は、以前のバージョンの Object Pascal ではRealと呼ばれていました。Delphi で古い 6 バイトの Real 型を使用するコードを再コンパイルする場合は、それをReal48に変更することをお勧めします。{$REALCOMPATIBILITY ON} コンパイラ ディレクティブを使用して、Realを 6 バイト型に戻すこともできます。次の注意事項は、基本的な実数型に適用されます。

  • Real48は下位互換性のために維持されています。そのストレージ形式は Intel プロセッサ アーキテクチャに固有のものではないため、他の浮動小数点型よりもパフォーマンスが低下します。
  • Extendedは、他の実数型よりも高い精度を提供しますが、移植性は低くなります。プラットフォーム間で共有するデータ ファイルを作成する場合は、Extended の使用に注意してください。

範囲が有効桁数よりも大きいことに注意してください。そのため、より大きな数を正確に格納できます。それが起こらないように、有効数字に丸めることをお勧めします。

于 2008-09-29T19:28:05.093 に答える
2

WriteLnを使用して実数の精度を指定する場合は、次を使用します。

WriteLn(RealVar:12:3);

少なくとも12の位置と3の精度で値Realvarを出力します。

于 2008-09-29T21:01:40.467 に答える
0

まず最初に、さまざまな引数でStrを使用したり、アプリの型の精度を上げたりすることで、何か助けが得られるかどうかを確認します。(Extendedを使用してみましたか?)

最後の手段として、(警告!回避策!!)顧客の文字列表現をバイナリ表現と一緒にソートされたリストに保存してみます。浮動小数点値を書き戻す前に、テーブルに一致する値がすでにあるかどうかを確認します。その文字列表現はすでにわかっており、代わりに使用できます。このルックアップをすばやく取得するために、数値でソートし、バイナリ検索を使用して最適なものを見つけることができます。

于 2008-09-29T19:34:00.850 に答える
0

ExportRealValue と ImportRealValue がどのタイプであるかを知らずにこれに答えるのは難しいです。他の人が述べたように、実際の型はすべて異なる精度を持っています。

いくつかの考えに反して、extended が常により高い精度であるとは限らないことに注意してください。拡張は 10 から 20 の有効数字で、double は 15 から 16 です。10 番目の sig fig 付近で問題が発生しているため、すでに拡張を使用している可能性があります。

読み取りと書き込みをより詳細に制御するには、数値を文字列に変換したり、文字列から変換したり、ファイル ストリームに書き込むことができます。少なくともそうすれば、readln と writeln が背後でうまくいかなくても心配する必要はありません。

于 2008-10-16T04:41:06.697 に答える
0

必要な処理の量によっては、元の精度を維持するために数値を BCD 形式のままにすることもできます。

于 2008-10-01T08:28:14.273 に答える
0

浮動小数点型を使用する場合、指定された型の精度制限に注意する必要があります。たとえば、4 バイトの IEEE-754 タイプの有効桁数は約 7.5 桁のみです。8 バイトの IEEE-754 型では、有効桁数が約 2 倍になります。どうやら、Delphi の実数型の精度は有効数字 11 桁程度です。この結果、指定した余分な桁数の書式設定は、基数 10 の書式設定された値と基数 2 の浮動小数点値の間の変換につながる可能性のあるノイズになる可能性があります。

于 2008-09-29T19:11:51.293 に答える