1

私は例えばこのコードを持っています:

(a) writeln ('real => ', exp(3*Ln(3)):0:0);  // return 27
(b) writeln ('int => ', int(exp(3*Ln(3))):0:0); // return 26

バグですか?関数calc3^ 3(lnおよびexp関数を使用した指数)が、realからintへの変換は失敗します。(a)が27を返す場合、(b)が(26)を返す場合、両方が27である必要があります。私はそれを解決できるので?助けてくれてありがとう。

PS:truncを使用して、結果を整数変数に割り当てすぎると、結果は変更されません。

4

5 に答える 5

9

いいえ、バグではありません。コンピューターには無限の精度がないため、結果は正確に27 ではなく、おそらく 26.999999999 か​​何かになります。そのため、youintまたはtruncit の場合は 26になりRoundます。代わりに使用します。

于 2011-09-08T17:16:37.727 に答える
6

出力している式は、通常の浮動小数点エラーにより、27 よりわずかに小さい値に評価されます。コンピューターは 3 の自然対数を正確に表すことができないため、これに基づいてさらに計算を行うとエラーが発生します。

コメントでは、exp(3*ln(3)) = 27.000 と主張していますが、そのアサーションのプログラムによる証拠は示していません。あなたのコードは exp(3*ln(3)) = 27 と言っていますが、これはあまり正確ではありません。精度を下げるように明示的に指示したため、それが出力されます。 パーツは単なる装飾ではありませんこれは、結果を小数点以下 0 桁で印刷することを意味します。そうするように指示すると、その小数点以下の桁数に丸められます。この場合、切り上げます。しかし、 の呼び出しを導入すると、ほぼ 27 の値が正確に 26 に切り捨てられ、出力する前に単純に 26 に丸められます。WriteLn:0:0WriteLnIntWriteLn

WriteLn小数点以下の桁数を増やすように指示すると、異なる結果が表示されるはずです。コロンの後の数字の意味の詳細については、ドキュメントを参照してください。Write

于 2011-09-08T18:44:28.493 に答える
2

浮動小数点を操作しても、常に 100% 正確な結果が得られるとは限りません。その理由は、バイナリ浮動小数点変数が常に値を正確に表現できるとは限らないためです。10 進数についても同じことが言えます。6 桁の精度の 10 進数で 1/3 を取ると、0.333333 になります。次に、0.333333 * 3 = 0.999999 を取るとします。整数 (0.999999) = 0

ここにそれに関するいくつかの文献があります...

すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

于 2011-09-08T17:43:06.997 に答える
1

また、Rudy Velthuis の記事もご覧ください。

http://rvelthuis.de/articles/articles-floats.html

于 2011-09-08T19:41:44.073 に答える
0

バグではありません。これは、浮動小数点演算がコンピューター上でどのように機能するかを示すもう 1 つの例です。浮動小数点演算は、実数が数学でどのように機能するかの近似値にすぎません。浮動小数点の結果が無限に正確であるという保証はありません。実際、ほとんどの場合、ある程度不正確であると予想する必要があります。

于 2011-09-08T17:21:51.563 に答える