2013-12-11 26 views
3

有人可以解釋以下內容。我有一個接受一對float64的函數,然後使用這個值來計算很多其他值。該功能看起來像GoLang爲浮動循環創建錯誤

func (g *Geometry) CalcStresses(x, zmax, zmin float64)(Vertical) 

結果被放入一個結構類似

type Vertical struct { 
    X float64 
    Stresses []Stress 
} 

現在有趣的事情是這樣的。如果我像這樣調用函數;

for i:=14.0; i<15.0; i+=0.1{ 
    result := geo.CalcStresses(i, 10, -10) 
} 

然後我得到了很多結果,其中的壓力數組是空的,antoher有趣的細節是,X有時顯示像數與小數的很多(如14.3999999999999999998)

但是,如果我叫像這樣的功能;

for i:=0; i<10; i++{ 
    x := 14.0 + float64(i) * 0.1 
    result := geo.CalcStresses(x,10,-10) 
} 

然後一切都很好。

有誰知道爲什麼會發生這種情況?

由於提前, 羅布

+1

您可能會發現這些資源有所幫助:http://www.validlab.com/goldberg/paper.pdf和http://floating-point-gui.de/ – Volker

+0

哇,謝謝沃爾克,這絕對是我可以得到的最全面的答案:-)偉大的紙,thx! – BreinBaas

回答

5

並非所有的實數能精確地以二進制浮點格式來表示,因此遍歷浮點數是自找麻煩。

維基百科上Floating point

浮點數字不能精確代表所有實數,而浮點運算不能精確代表真正的算術運算的事實,導致許多奇怪的情況。這與計算機通常表示數字的有限精度有關。

例如,0.1和0.01(二進制)的不可表示性意味着嘗試平方0.1的結果既不是0.01也不是最接近它的可表示數。

This code

for i := 14.0; i < 15.0; i += 0.1 { 
    fmt.Println(i) 
} 

產生此

14 
14.1 
14.2 
14.299999999999999 
14.399999999999999 
14.499999999999998 
14.599999999999998 
14.699999999999998 
14.799999999999997 
14.899999999999997 
14.999999999999996 

您可以使用math.big.Rat類型來準確地表示有理數。

Example

x := big.NewRat(14, 1) 
y := big.NewRat(15, 1) 
z := big.NewRat(1, 10) 

for i := x; i.Cmp(y) < 0; i = i.Add(i, z) { 
    v, _ := i.Float64() 
    fmt.Println(v) 
}