2011-09-08 94 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以瞭解冒號後的數字。

相關問題