1

例如,我有以下代码:

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

是错误吗?函数 calc 3^3(指数使用 ln 和 exp 函数),但从 real 到 int 的转换失败;情况(a)返回 27,情况(b)返回(26),什么时候都应该是 27。我能解决吗?非常感谢您的帮助。

Ps:将结果分配给整数变量,使用 trunc,结果不会改变。

4

5 回答 5

9

不,这不是错误。计算机根本没有无限的精度,所以结果不完全是27,而可能是 26.999999999 之类的。因此,当您inttrunc它时,它最终为 26。请Round改用。

于 2011-09-08T17:16:37.727 回答
6

由于通常的浮点错误,您正在打印的表达式的计算结果略小于 27。计算机不能准确地表示 3 的自然对数,因此任何基于它的进一步计算也会有错误。

在评论中,您声称 exp(3*ln(3)) = 27.000,但您没有显示该断言的程序证据。您的代码显示 exp(3*ln(3)) = 27,这不太精确。它会打印出来,因为您明确告知 WriteLn要使用较低的精度。:0:0部分不仅仅是装饰。这意味着您要打印零小数位的结果。当您告诉WriteLn这样做时,它会四舍五入到那么多小数位。在这种情况下,它向上取整。但是,当您引入对 的调用时,您会将Int几乎27 的值截断为正好 26,然后WriteLn在打印之前将其简单地四舍五入为 26。

如果您告诉WriteLn显示更多小数位,您应该会看到不同的结果。有关冒号后数字含义的详细信息,请参阅文档。Write

于 2011-09-08T18:44:28.493 回答
2

使用浮点数并不总是能给出 100% 的准确结果。原因是二进制浮点变量不能总是准确地表示值。十进制数也是如此。如果取 1/3,以 6 位精度十进制表示,将是 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

不是错误。这只是浮动算术如何在计算机上工作的又一个例子。浮点运算只是实数在数学中如何工作的近似值。无法保证,也无法保证浮点结果将无限准确。事实上,你应该期望它们在某种程度上几乎总是不精确的。

于 2011-09-08T17:21:51.563 回答