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 표면에 와이어 메시로 도식화 함.