我有这个代码,例如:
(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,结果不变。
答案 0 :(得分:9)
不,这不是一个错误。计算机根本没有无限精度,因此结果不是完全 27,但可能是26.999999999或其他东西。因此,当您int
或trunc
时,结果为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的文章:
答案 4 :(得分:0)
不是错误。这是浮动算法如何在计算机上运行的另一个例子。浮点算术只是实数在数学中如何工作的近似值。没有保证,并且没有这样的保证,浮点结果将是无限准确的。事实上,你应该期望它们在某种程度上几乎总是不精确。