2011-09-08 158 views
1

我有例如下面的代码:为什么使用real的计算给出了使用int的不同结果?

(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,结果不变。

+0

负。对象之前已经讨论过千次。 –

+0

@Downvoter,在这种情况下,您应该投票结束重复问题的链接。 – Johan

+0

[为什么是RoundTo(87.285,-2)=> 87.28]的结果的重复(http://stackoverflow.com/questions/5191235/why-is-the-result-of-roundto87-285-2- 87-28) – Johan

回答

9

不,这不是一个错误。计算机根本没有无限的精度,所以结果不是,正好是 27,但也许是26.999999999什么的。所以,当你inttrunc它,它结束为26.使用Round来代替。

+0

它也是当真实是:27.000? 27000到26000回合是什么意思?我不明白。 –

+0

'int'返回其参数的整数部分,也就是说,它的参数舍入为零。 'trunc'做同样的事情,但返回一个整数(作为数据类型)。舍入到最接近的整数。那就是你想要的。 –

+0

但函数:exp(3 * ln(3))返回27.000,而不是26.9999999 –

0

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

+0

了解,但如前所述,第一种情况下的结果为27.000,第二种情况下的结果为26.000。并且函数calc 3 * 3 * 3(以实际格式)有点为:3.000 * 3.000 * 3.000 = 27.000;这是从小数部分的这种approssimation在哪里?但是一般情况下,如果我要像以前那样精确地计算x^n(n> = 0),而不使用数学函数?如需要,需要使用基于的复杂功能吗?没有更简单吗?我知道如此解决,但我试着用优雅的解决方案。 –

2

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

下面是一些关于它的litterature ...

What Every Computer Scientist Should Know About Floating-Point Arithmetic

+0

我认为标题很具误导性。忽略用户手册**的人也会忽略针对“科学家”的出版物。同时,本文包含在**接近电机之前需要熟悉**的绝对强制性信息。 –

6

你打印的计算结果为东西比27略少,由于平时的浮点错误的表达。计算机不能准确表示3的自然对数,所以基于它的任何进一步计算也会有错误。

在注释中,您声明exp(3 * ln(3))= 27.000,但您没有显示该断言的程序化证据。你的代码表示exp(3 * ln(3))= 27,这是不太精确的。它打印的是因为你明确地告诉要求WriteLn使用较少的精度。 :0:0部分不只是装饰。这意味着您要打印带有小数点后0位的结果。当你告诉WriteLn这么做时,会将舍入到那么多小数位。在这种情况下,它收起。但是当你引入Int的呼叫时,你截去几乎-27的值到26,然后WriteLn把它打印到26之前打印它。

如果您告知WriteLn显示更多小数位,您应该看到不同的结果。请查阅documentation for Write以了解冒号后的数字。

相关问题