2013-12-11 1 views
3

누군가가 다음을 설명 할 수 있습니까? 나는 몇 가지 float64를 받아 들인 다음이 값을 사용하여 많은 다른 값을 계산하는 함수가 있습니다. 결과가GoLang for floats가 오류를 생성 함

type Vertical struct { 
    X float64 
    Stresses []Stress 
} 

같은 구조체에 넣고

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

같은 기능은 이제 재미있는 점은 이것이다 보인다. 만약 내가이 함수를 호출하면; 다음

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

나는 스트레스 배열이 비어 결과를 많이 얻을 antoher 흥미로운 세부 때로는

그러나 (14.3999999999999999998 같은) 소수의 많은 숫자처럼 보여 x를 내가 호출하는 경우이다 이 같은 기능;

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

와우, 감사합니다 Volker, 이것은 확실히 내가 가질 수있는 가장 포괄적 인 대답이다 .-) Great paper, thx! – BreinBaas

답변

5

모든 실수 따라서 이상의 부동 소수점 숫자 문제에 대한 요구하고있다 루핑, 정확히 이진 부동 소수점 형식으로 표현 될 수있다. Floating point

부동 소수점 숫자는 정확하게 모든 실수를 표현 할 수없는 및 부동 소수점 연산이 정확하게 사실 산술 연산을 대표 할 수 있다는 사실에 위키

많은 놀라운 상황에 이르게. 이것은 컴퓨터가 일반적으로 숫자를 나타내는 유한 정밀도와 관련이 있습니다.

예를 들어, 0.1과 0.01의 비 표현성 (이진수로 표현)은 0.01을 제곱하려고 시도한 결과가 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) 
}