2009-09-09 14 views
5

次のコードを見て、Trunc関数の結果が異なるのはなぜですか?Trunc()function

procedure TForm1.Button1Click(Sender: TObject); 
var 
    D: Double; 
    E: Extended; 
    I: Int64; 
begin 
    D := Frac(101/100) * 100; 
    E := Frac(101/100) * 100; 
    I := Trunc(D); 
    ShowMessage('Trunc(Double): ' + IntToStr(I)); // Trunc(Double): 1 
    I := Trunc(E); 
    ShowMessage('Trunc(Extended): ' + IntToStr(I)); // Trunc(Extended): 0 
end; 

答えて

9

フォーマット機能は、常に実際の数字(データ)を表示しません。
実数と精度は難しい場合があります。

は私が画面上に表示する内容に、より精度を使用して、このコードをチェックアウト:

D := Frac(101/100); 
    E := Frac(101/100); 
    ShowMessage(FloatToStrF(D, ffFixed, 15, 20)); 
    ShowMessage(FloatToStrF(E, ffFixed, 18, 20)); 

E0.00999999999のようなものである一方、D0.010000000000のようなものであることが表示されます。

編集:Extendedタイプの精度がDoubleタイプよりも優れています。 FloatToString()でDとEの値を表示しようとすると、実際の値が同じではなくであっても、おそらく同じ結果()が得られます。

6

注意ニックDの答え。

Dは 0.010000000000のようになりますが、Eは0.00999999999のように見えます。

しかし、答えは書式設定機能ではありません。これは、浮動小数点計算がどのように行われるかです。コンピュータは浮動小数点数を理解できません(コンピュータは有限のビット数とバイト数で動作しますが、0と1の間には無制限の数値があるため)。また、Delphi(および他のほとんどの言語)の各DoubleまたはExtended変数は単なる近似値(実際にはまれな例外がいくつかあります)。

あなたがウィキペディア上での詳細を読むことができます:Floating pointFixed-point

+0

smok1、私たちは多くの場合、適切な形式のパラメータなしでフロート番号を調べて、我々は実際の値を取得することを前提としています。あなたが正しく言及したように、浮動小数点数は実際の数の近似値なので、もちろん間違っています。 +1 –

+1

コンピュータが浮動小数点を近似値として格納することを説明するための+1 –

+2

すべての浮動小数点は近似ではありません。 2の負のべき乗とそれらの和(例えば0.5)は近似することなく表される。 – gabr