2013-02-13 58 views
4

據我所知,浮點類型的值必須仔細比較以避免固有浮點錯誤的問題。通過比較值和錯誤閾值可以改善這一點。比較float和double值與delta嗎?

例如,下面的解決方案比一個簡單的測試x == y更多的可用:

static float CompareRelativeError(float x, float y) { 
    return Math.Abs(x - y)/Math.Max(Math.Abs(x), Math.Abs(y)); 
} 
static bool CompareAlmostEqual(float x, float y, float delta) { 
    return x == y || CompareRelativeError(x, y) < delta; 
} 

// apologies if this is a poor example 
if (CompareAlmostEqual(1f/10f, 0.1f)) { ... } 

將上述溶液從下面的資源衍生的: Is it safe when compare 2 float/double directly in Java?

雖然我還沒有能找到任何文學來證實這一點,對我來說,似乎相同必須適用於比較,如x > y。例如,如果xy基本上是相等的,怎麼能一個比其他更大...

static bool CompareGreater(float x, float y, float delta) { 
    return x > y && !CompareAlmostEqual(x, y, delta); 
} 

因此建立了下面將爲x >= y是有效的:

static bool CompareGreaterOrEqual(float x, float y) { 
    return x >= y; 
} 

是我的假設是否正確?

+0

可能重複[Doub le.Epsilon for equal,大於,小於,小於或等於,大於或等於](http://stackoverflow.com/questions/2411392/double-epsilon-for-equality-greater-thanless - 小於或等於gre) – 2013-02-13 01:02:27

回答

4

等式測試正是delta(或epsilon)技術用於浮點值的原因。

例如我們希望3等於2.999999 ...以某種精度。

static bool CompareGreaterOrEqual(float x, float y) { 
    return x >= y; 
} 

它應該是::

因此,當定義爲您的CompareGreaterOrEqual方法是不夠的

static bool CompareGreaterOrEqual(float x, float y, float delta) { 
    return x >= y || CompareAlmostEqual(x, y, delta); 
} 

注:x >= y在第一次測試可能只是x > y因爲增量比較需要的護理等於:

static bool CompareGreaterOrEqual(float x, float y, float delta) { 
    return x > y || CompareAlmostEqual(x, y, delta); 
} 
+0

非常感謝你們的幫助!這是一個寫得很好的答案,我現在明白爲什麼'CompareAlmostEqual'在這裏也需要。 – 2013-02-13 01:07:49

2

既然我們已經同意在這種情況下運營商=是通過CompareAlmostEqual完成的,那麼在CompareGreaterOrEqual中使用它也是有意義的。

static bool CompareGreaterOrEqual(float x, float y, float delta) { 
    return x >= y || CompareAlmostEqual(x, y, delta); 
} 

此外,雖然它在很大程度上取決於你將如何使用這些功能的,我也會使delta是整個類使用的常數變量,以確保使用相同的值(而不是周圍將它作爲一個參數)。

+0

+1。擊敗我! ;) – 2013-02-13 01:04:18

+1

@MitchWheat - 實際上根據我們的回答來看時間,我相信*你*是勝利者,先生! – 2013-02-13 01:05:46