2013-01-22 45 views
0

我有一個內聯函數進行頻率到週期的轉換。計算精度必須使用類型,而不是類型。否則,它可能會導致一些舍入錯誤。該功能然後將結果轉換回double。我想知道在下面的代碼中,哪一行將保持計算類型。無論參數欄是100,100.0還是33.3333。類型爲「long」的C++計算

double foo(long bar) 
{ 
    return 1000000/bar; 
    return 1000000.0/bar; 
    return (long)1000000/bar; 
    return (long)1000000.0/bar; 
} 

我自己試了一下,第四行工作。但在這種情況下,只是想知道類型轉換的概念。

編輯:

其中一個錯誤的是37038分之1000000= 26,不26.9993。

+3

大家知道,存儲在double中的整數值不會有舍入誤差,除非它超出了尾數的範圍,通常是2 ** 52。 –

+1

當長時間通過時bar不能爲33.3333。它將被轉換爲33. – Axel

+3

bar不可能是'100.0'或'33.3333'。你應該使用1000000L作爲常數。 – stefan

回答

1

這個問題,正如你提出的那樣,沒有任何意義。

bar是整體式的,所以1000000/bar一定會小於1000000,它可以準確地由double 來表示,所以沒有辦法在所有積分算術進行計算可以提供更好的精度 - 實際上,你會得到整數除法,在這種情況下,減去精確的任何值bar,因爲它會截斷小數部分。這裏longdouble轉換的問題的唯一方法是在bar轉換爲double,但是如果它超出double的範圍,除法的最終結果將爲0,因爲無論如何整數算術中都是如此。

靜像:

1000000/bar 

執行long s之間的劃分:1000000是intlong,取決於平臺,barlong;如有必要,第一個操作數被提升爲long,然後執行整數除法。

1000000.0/bar 

執行除法double S之間:1000000.0double文字,所以bar被分割之前升爲double

(long)1000000/bar 

等同於第一個:鑄造具有優先於分裂,和力1000000(其是一個longint)是一個long; barlong,執行long之間的劃分。

(long)1000000.0/bar 

相當於前一個:1000000.0double,但是你把它轉換爲long然後整數除法進行。


  1. C標準,其中C++標準委託事項,請求用於double S(DBL_DIG)和至少10**37 10的作爲可表示功率的尾數最少10個十進制數字到去之前超出範圍(DBL_MAX_10_EXP)(C99,附件E,¶4)。
+0

「,它可以完全用雙」< - False「表示。十分之一不能用二進制IEEE表示法完全表示,就像三分之一不能用有限十進制擴展表示的那樣。 – 2013-01-22 16:50:54

+0

@Tinctorious:那「which」是指1000000',那*可*完全由'double'表示。分割的結果可能會或可能不會完全表示,但在這種情況下,「double」分割比「long」分割(截斷小數部分)的分割精度要高。 –

+1

@Tinctorius他說「1000000」可以完全表示爲「雙」。在形式上,我不確定它是由C++標準保證的,但我從來沒有聽說過一個實現不正確的實現。 –

2
return 1000000/bar; 

這會做一個長的數學。

return 1000000.0/bar; 

這將做數學題的兩倍。

return (long)1000000.0/bar; 

這相當於第一 - 1000000.0是雙,但你分割之前將其轉換爲長,所以該司將在多頭做。

1

第一行(和第三個更詳細地)將做數學long(在C++中總是截斷任何結果),然後返回整數值作爲double。我不明白你在關於bar的問題中說的是33.3333,因爲這不是long的值。

相關問題