Golang

[Go] The Go Programming Language #3-2: 부동소수점 수 (실수)

leejiwonn 2021. 11. 30. 15:47

 

이 시리즈는 "The Go Programming Language" 책을 바탕으로 작성되었습니다.

 

3.2  부동소수점 수 (실수)

  • 이 수의 산술적 속성은 모든 현대 CPU에 의해 구현된 IEEE 754 표준을 따름.
  • 부동소수점 값의 한계는 math 패키지에서 찾을 수 있음.
    • 상수 math.MaxFloat32 는 가장 큰 float32 로 약 3.4e38 이며, math.MaxFloat64 는 약 1.8e308 임.
    • 가장 작은 양의 값은 각각 1.4e-45 와 4.9e-324 근처임.

실수 타입 종류

  • float32 : 대략 6자리 10진 숫자의 정확도를 가짐.
  • float64 : 대략 15자리의 정확도를 가짐.
  • 대부분의 경우 float64를 사용해야 함. 왜냐하면 float32 연산에서는 신중하게 처리하지 않을 경우 오류가 빠르게 누적되는데, float32로 표현할 수 있는 최소 양의 정수가 별로 크지 않아 문제가 되기 때문임.
    var f float32 = 16777216  // 1 << 24
    fmt.Println(f == f+1)     // "true"!​

지수 표기법

  • 부동소수점 숫자는 다음과 같이 10진법으로 작성할 수 있음.
    const e = 2.71828  // (대략)
  • 단, 아주 작거나 아주 큰 숫자는 10진 지수 앞에 문자 e나 E로 지수를 나타내는 지수 표기법으로 쓰는 것이 좋음.
    const Avogadro = 6.02214129e23
    const Planck = 6.62606957e-34
  • 부동소수점 값은 적절한 정확도의 가장 간결한 표현을 선택하는 Printf의 %g로 편리하게 출력할 수 있지만, 데이터 테이블의 경우 %e(지수) 또는 %f(지수 없음) 형태가 더 적합할 수 있음.
  • %g, %e, %f 모두 필드의 길이와 수치 정밀도를 제어할 수 있음.
    // 이 코드는 e의 지수를 3자리 정밀도의 10진 숫자로 출력하며, 8글자 필드로 정렬함.
    for x := 0; x < 8; x++ {
    	fmt.Printf("x = %d e^(x) = %8.3f\n", x, math.Exp(float64(x)))
    }
    
    /* 출력 결과 :
    x = 0  e^(x) =    1.000
    x = 0  e^(x) =    2.718
    x = 0  e^(x) =    7.389
    x = 0  e^(x) =   20.086
    x = 0  e^(x) =   54.598
    x = 0  e^(x) =  148.413
    x = 0  e^(x) =  403.429
    x = 0  e^(x) = 1096.633
    */​

math 패키지

  • 이 패키지에는 다수의 일반적인 수학 함수들 외에도 IEEE 754에 의해 정의된 특별한 값을 생성하고 검출하는 함수가 있음.
    ⇒ 아주 큰 수를 나타내는 양과 음의 무한대 값과, 수학적으로 모호한 연산인 0/0이나 Sqrt(-1) 의 결과인 NaN (Not a Number : 숫자가 아님) 을 뜻함.
    var z float64
    fmt.Println(z, -z, 1/z, -1/z, z/z)  // "0 -0 +Inf -Inf NaN​
  • math.IsNaN 함수는 인자가 숫자가 아닌 값인지 테스트하고, math.NaN 은 NaN 값을 반환함.
  • NaN을 산술 연산의 유효성 검증 값으로 사용하는 것은 위험함. NaN과의 비교 결과는 항상 false이기 때문임.
    nan := math.NaN()
    fmt.Println(nan == nan, nan < nan, nan > nan)  // "false false false"​
  • 부동소수점 결과를 반환하는 함수에서 실패할 것이 예상되면 다음과 같이 실패를 별도로 보고하는 것이 좋음.
    func compute() (value float64, ok bool) {
    	// ...
    	if failed {
    		return 0, false
    	}
    	return result, true
    }

부동소수점 그래픽 연산 예제

  • 이 프로그램은 두 변수로 이뤄진 함수 z = f(x, y) 를 선 그리기용 XML 표준 표기법인 SVG 를 이용해 3D 표면에 와이어 메시로 도식화 함.