名前 題名 ▼ Mr.XRAYさん > >今度は,64 ビットのEXE を作成して実行してみます. > >やはり,e と f の表示が違います. > > 当サイトに次のような記事があります. > これとも関係してきます. > > [890_計算誤差 ( 数値計算の誤差 ) と多倍長演算] > http://mrxray.on.coocan.jp/Delphi/plSamples/890_CalcError.htm > > サンプルの > > e:=(a+b+c)*d; //(1) > f:=a*d+b*d+c*d; //(2) > > e と f の値は,数学的には同じでも,コンピュータ内部では異なる場合があります. > FloatToStr 関数は,数値を文字列にする際,15 桁で丸めます. > 一方,SimpleRoundTo 関数は,元の値を使用して四捨五入します. > > このことを利用すると,数値を一度 FloatToStr 関数で文字列にして, > 再度実数にすれば,16 桁以上の精度があれば,計算結果の違いを回避すること > ができることになります. > 今回のような単純な計算であれば利用可能でしょう. > そのテスト用コードです. > > //----------------------------------------------------------------------------- > // (1)と(2)の計算式は,数学的には等しく,179.935となる > //----------------------------------------------------------------------------- > procedure TForm1.Button1Click(Sender: TObject); > var > a,b,c,d,e,f:Extended; > strText : String; > begin > a:=389.7; > b:=94.4; > c:=30; > d:=0.35; > e:=(a+b+c)*d; //(1) > f:=a*d+b*d+c*d; //(2) > > //StrToFloatは15桁で丸めを行うので15桁に丸めた文字列を取得する > //その文字列を再度実数にする > e := StrToFloat(FloatToStr(e)); > f := StrToFloat(FloatToStr(f)); > > StrText := FloatToStr(e)+#13+ > FloatToStr(f)+#13+ sLineBreak + > FloatToStr(SimpleRoundTo(e,-2))+#13+ > FloatToStr(SimpleRoundTo(f,-2)); > MessageBox(Handle, PChar(strText), '結果', MB_OK); > end; > > > 下図が実行結果です. > 指定小数点以上の精度が必要ないか,計算の結果の精度が分かっている場合, > 次のように,計算の結果をその小数点の桁数に四捨五入してしまう方法も > 考えられます. > > e := SimpleRoundTo(e, -10); > f := SimpleRoundTo(f, -10); > > この他,FloatToStrF 関数, FloatToText 関数 や FloatToTextFmt 関数で, > 精度を指定する方法もあります. > > FloatToStrF(f, ffFixed, 10, 2)) > > は,10 桁の精度で,固定小数点形式の小数点 2 桁までの値の文字列を取得します. > > [System.SysUtils.FloatToStrF - RAD Studio API Documentation] > http://docwiki.embarcadero.com/Libraries/XE6/ja/System.SysUtils.FloatToStrF > > GIF,JPEG,PNG画像ファイル及びLZH,ZIPファイルをアップロードできます.600 x 1200 ピクセルを超える画像は縮小表示されます(画像クリックで拡大表示). (上限122000(120k)バイト) 削除キー Link