2013-03-12 35 views
1

可以result永遠是假的,因爲4/2.0可能會返回類似1.99999999?更普遍比標題:浮點錯誤會導致'a /(double)b> = a/b'失敗嗎?

int a = // any valid int 
int b = // any valid int 
boolean result = (a/(double)b) >= a/b; 

如果這是可能的,任何人都可以提供的ab的例子嗎?如果這是不可能的,是否有Java或浮點規範證明了這一點?

我幾分鐘前寫了這個邏輯,並且突然擔心它突破。我一直無法打破它,但我想知道是否可以跨所有JVM保證。

回答

5

如果ab是正值int值,則a/(double)b >= a/b

我使用下面的處所,以理解的語義,例如的a/bint值將被轉換爲double用於與>=其它操作數的比較一起。

物業:

  • int的範圍爲[2,147,483,648,2147483648)。
  • double是IEEE 754 64位二進制。
  • 舍入模式是舍入到最近的。
  • 所有的浮點操作,特別是除法,符合IEEE 754.
  • 整數a/b截斷爲零。

記號:

  • 一個a數學值。是b的數學值。
  • 數學表達式,如 a/ b,與計算表達式(如a/b)不同。
  • L是爲a/(double)b產生的價值。
  • R是爲a/b產生的價值。

證明:

  • 所有int值是double表示的,所以IEEE 754要求轉換intdouble是準確的。
  • 因此,(double) a(double) b產生一個b準確,和a/(double)b產生一個/ b正確地四捨五入到最接近的double
  • 由於- [R一個/ b朝向零,和一個/ b是陽性截斷,- [R是地板(一個/ b)。
  • 最大 a/ b可以是2,147,483,647/1 = 2,147,483,647。在這個數量級以下的每個整數可以精確表示爲double
  • 大號double最近一個/ b。如果L減小四捨五入,則減小到下一個較低的double。由於在該級的所有整數表示的是,地板(一個/ b)可表示,所以大號是至少地板(一個/ b)。
  • 因此LR
  • - [Rdouble是精確的轉化,所以大號- [R>=比較產生相同的結果爲數學大號- [R
+0

非常感謝您的迴應! – 2013-03-12 06:29:32

0

4/2.0必須返回2.0,因爲浮點除法是確切的。

負數可能會導致您的比較失敗,但。請注意0​​,而-1.0/2.0 = -0.5

+1

+1爲例。然而,「浮點除法師確切」需要一定的資格;你究竟是什麼意思? – 2013-03-12 00:47:46

+0

也因爲那些是二進制數字,不是嗎? '4/2.0'是'4 * 2 ^( - 1)',IIRC是如何存儲浮點數的。 – wchargin 2013-03-12 00:48:12

+0

@OliCharlesworth:兩個浮點數的除法總是將最接近的浮點數返回給商。 – tmyklebu 2013-03-12 00:48:23

2

對於負數,這對於= -10失敗,B = 3

對於正投入而已,我想你是安全的。

令x爲a除以b的實數結果。

首先考慮x可表示爲int的情況。它也可以表示爲double,並且兩個計算都返回x。

現在假設x不是int。問題是x和a /(double b)之間舍入誤差的絕對值是否超過a/b的截斷誤差。這不可以。

截斷誤差t = x - a/b必須至少爲1/b。 x不能大於Integer.MAX_VALUE/b,所以t/x至少爲1/Integer.MAX_VALUE。這比正確舍入的雙重計算的最大舍入誤差要大得多。

相關問題