2016-08-23 99 views
0

我看到一個問題,並不太明白。倍增變量

第一我們創建任意值:

int x = random(); 
int y = random(); 
int z = random(); 

(int是32位) 然後繼續:

double dx = (double) x; 
double dy = (double) y; 
double dz = (double) z; 

(雙爲64位)

問題是告訴如果下一個陳述是總是是真(返回1)或不。

a. dx+dy+dz==dz+dy+dx 

b. dx*dy*dz==dz*dy*dx 

答案(一)說:「是,在由雙的範圍內精確表示的」 (是這樣,它還是不總是真的嗎?如果是不總是真實, (b)的答案是「否,例如dx = Tmax,dy = Tmax-1,dz = Tmax-2」 (dx,dy,dz,返回0的3個值的示例)

我試過了,結果是相同的結果(但很有可能我錯了: - /)

我想了解爲什麼那些答案是正確的

謝謝!

回答

1

在浮點運算中,您應該從不測試是否相等。一個典型的例子是0.1 + 0.2 != 0.3。 (有關更多信息,請參閱http://0.30000000000000004.com/以瞭解更多信息,特別是查看您的語言是否隱藏了此內容。它很好地解釋了這種情況,因爲0.1和0.3不能用雙精度表示。)應該檢查浮點值看看它們是否在一定範圍內足夠接近,通常稱爲「寬容」。

見IEEE 754的定義:https://en.wikipedia.org/wiki/Double-precision_floating-point_format

我的答案不同意(A),因爲它是毫無意義的,指定什麼可以「精確表示」由雙 - 如果每個輸入的雙重表示給定隨機位(x,y,z),那麼根據定義,它就是精確的表示。另外,可以說「是的,但只在某些條件下」作爲答案「是否這個總是是真的?」在這種情況下的答案是「否」。 (a)的一個反例如下。我通過考慮浮點數只具有一定的相對精度來構造這一點,因此將非常小的數添加到非常大的數可能沒有區別。讓這個小號碼足夠大,它會。

  • 1e16 + 1 + 1 = 10000000000000000
  • 1 + 1 + 1e16 = 10000000000000002

作爲(b)中,我試圖隨機的第一件事情是一個反:

  • 0.1 * 0.1 * 0.7 = 0.007000000000000001
  • 0.7 * 0.1 * 0.1 = 0.006999999999999999