質問

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

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

エクスポートしてからインポートとエクスポートを再度行い、ファイルを比較すると、最後の2桁に違いがあります(例:実際の桁数はずれている可能性がありますが、取得できます):

-1.23456789012E-0002
-1.23456789034E-0002

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

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

役に立ちましたか?

解決

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

WriteLn(RealVar:12:3);

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

他のヒント

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

Delphiヘルプから:

基本的なWin32実数型

                                            | Significant | Size in 
Type     | Range                            | digits      | bytes
---------+----------------------------------+-------------+----------
Real     | -5.0 x 10^–324 .. 1.7 x 10^308   | 15–16       |   8  
Real48   | -2.9 x 10^–39 .. 1.7 x 10^38     | 11-12       |   6   
Single   | -1.5 x 10^–45 .. 3.4 x 10^38     |  7-8        |   4   
Double   | -5.0 x 10^–324 .. 1.7 x 10^308   | 15-16       |   8   
Extended | -3.6 x 10^–4951 .. 1.1 x 10^4932 | 10-20       |  10   
Comp     | -2^63+1 .. 2^63–1                | 10-20       |   8   
Currency | -922337203685477.5808..          |             | 
                    922337203685477.5807    | 10-20       |   8   
  

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

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

範囲が有効数字よりも大きいことに注意してください。そのため、正確に保存できる数よりも大きい数にすることができます。それを防ぐため、有効数字に丸めることをお勧めします。

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

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

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

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

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

いくつかの考えに反して、拡張は常により高い精度ではないことに注意する価値があります。拡張は10〜20桁の有効数字で、倍精度は15〜16桁です。 10桁目で問題が発生しているので、おそらく既に拡張機能を使用しています。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top