为什么使用real进行计算会得到使用int的结果?

时间:2011-09-08 17:11:43

标签: delphi math floating-point delphi-xe2

我有这个代码,例如:

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

是个bug吗? 函数calc 3 ^ 3(使用ln和exp函数指数),但是从real转换为int失败;如果(a)返回27,如果(b)返回(26),则何时应为27。 我能解决吗? 非常感谢您的帮助。

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

5 个答案:

答案 0 :(得分:9)

不,这不是一个错误。计算机根本没有无限精度,因此结果不是完全 27,但可能是26.999999999或其他东西。因此,当您inttrunc时,结果为26.请改用Round

答案 1 :(得分:6)

由于通常的浮点错误,您打印的表达式的计算结果略低于27。计算机无法准确表示3的自然对数,因此基于它的任何进一步计算也会出错。

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

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

答案 2 :(得分:2)

使用浮点并不总是能给出100%的精确结果。原因是二进制浮点变量不能总是精确地表示值。十进制数也是如此。如果采用1/3,精度为6位精度,则为0.333333。然后,如果你采取0.333333 * 3 = 0.999999。 Int(0.999999)= 0

以下是关于它的一些文章......

What Every Computer Scientist Should Know About Floating-Point Arithmetic

答案 3 :(得分:1)

你还应该看看Rudy Velthuis的文章:

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

答案 4 :(得分:0)

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