반응형
Go의 숫자형과 부동소수점 오류
- Go는 매우 엄격한 문법을 갖고 있기 때문에 동일한 값을 지녀도 형이 다르다면 연산이 불가
- Go 역시 부동소수점 오류를 갖기 때문에 연산을 위한 형변환 과정에서 주의가 필요
I. Go의 숫자형
1. 종류
- uint
- unsigned integers 로 0 ~ max value 까지 표현
- uint8/16/32/64
- uint로 선언할 경우 32 or 64bit으로 설정
- uint8은 byte와 동일한 값을 가짐
package main
import (
"fmt";
"math"
)
func main() {
uint8_num := uint8(3)
byte_num := byte(3)
fmt.Println("uint8 : ", uint8_num, ", byte : ", byte_num)
fmt.Println(uint8_num + byte_num)
}
>>> uint8 : 3 , byte : 3
>>> 6
- int
- signed integers 로 max_value의 보수까지 표현
- int8/16/32/64
- int로 선언할 경우 32 or 64bit으로 설정
- int32는 rune과 동일한 값을 가짐
package main
import (
"fmt";
"math"
)
func main() {
int32_num := int32(3)
rune_num := rune(3)
fmt.Println("int32 : ", int32_num, ", rune : ", rune_num)
fmt.Println(int32_num + rune_num)
}
>>> int32 : 3 , rune : 3
>>> 6
- float/complex
- 실수형(float32/64) 과 복소수형(complex64/128)
- complex64는 float32로 표현된 실수부와 허수부로 구성
II. Go 숫자형 연산
1. Overflow/Underflow
- 선언된 데이터 타입이 갖는 최대/최소값을 벗어나는 경우 발생하는 에러
- 사용할 데이터 범위가 정해져있는 상황에서는 데이터 타입을 지정하여 데이터 범위를 완벽히 제한하고 메모리 측면에서 살짝 이익을 볼 수 있으나, 그렇지 않은 경우 되도록 큰 비트수를 사용하는게 좋음
package main
import (
"fmt";
"math"
)
func main() {
var maxuint8 uint8 = math.MaxUint8 // 255
var overflow uint8 = math.MaxUint8 + 1
}
>>> constant 256 overflows uint8
2. 산술연산 예시
package main
import (
"fmt"
)
func main() {
n3 := int64(4)
n4 := int64(6)
fmt.Println("덧셈", n3+n4)
fmt.Println("뺄셈", n3-n4)
fmt.Println("나눗셈(몫)", n3/n4)
fmt.Println("나눗셈(나머지)", n3%n4)
fmt.Println("곱셈", n3*n4)
fmt.Println("비트이동 왼쪽", n3<<2)
fmt.Println("비트이동 오른쪽", n3>>2)
fmt.Println("보수", ^n3)
}
>>> 덧셈 10
>>> 뺄셈 -2
>>> 나눗셈(몫) 0
>>> 나눗셈(나머지) 4
>>> 곱셈 24
>>> 비트이동 왼쪽 16
>>> 비트이동 오른쪽 1
>>> 보수 -5
3. 부동소수점 오류
- 동일한 0.1 - 0.1 도 32비트에서와 64비트에서는 전혀 다른 결과를 출력
- 컴퓨터는 2진수로 모든 것을 표현하기 때문에 실수는 딱 떨어지는 숫자로 나타나지 않고 특정 비트까지 잘라서 표현하게되어 발생하는 오류
- 서로 다른 타입의 숫자형을 연산할 때는 정수보단 실수형에 맞추고, 큰 비트수에 맞추는게 좋음
package main
import (
"fmt"
)
func main() {
n1 := float32(.1)
n2 := float64(.1)
fmt.Println("float32 : ",n1)
fmt.Println("float32->float64 : ", float64(n1))
fmt.Println("float64 형변환 연산",float64(n1)-n2)
fmt.Println("float32 형변환 연산",n1-float32(n2))
}
>>> float32 : 0.1
>>> float32->float64 : 0.10000000149011612
>>> float64 형변환 연산 1.4901161138336505e-09
>>> float32 형변환 연산 0
- 부동소수점 차이는 항상 머신 입실론 값 이하
package main
import (
"fmt";
"math"
)
func main() {
epsilon := math.Nextafter(1,2)-1
fmt.Println("Go 의 머신 입실론 값 : ", epsilon)
}
>>> Go 의 머신 입실론 값 : 2.220446049250313e-16
** 머신입실론 : 컴퓨터의 부동 소수점 연산에서 1보다 큰 최소의 수와 1과의 차아로 반올림에 기인하는 상대 오차의 상한값.
반응형