1. 연산자
연산자 : Operator
컴퓨터 : 데이터를 계산 / 조작
기본적으로 변수, 연산자, 조건문(if문)만 있으면 코딩이 가능하다.
2. 연산자의 종류
(1) 사칙연산과 나머지
연산자 | 연산 | 피연산자타입 |
+ | 덧셈 | 정수, 실수, 복소수, 문자열 |
- | 뺄셈 | 정수, 실수, 복소수 |
* | 곱셈 | 정수, 실수, 복소수 |
/ | 나눗셈 | 정수, 실수, 복소수 |
% | 나머지 | 정수 |
(2) 비트 연산
연산자 | 연산 | 피연산자타입 |
& | AND 비트 연산 | 정수 |
| | OR 비트 연산 | 정수 |
^ | XOR 비트 연산 | 정수 |
&^ | 비트 클리어 | 정수 |
① &(AND 연산자)
A와 B가 1인 경우에만 1
A | B | A&B |
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
② | (OR 연산자)
A나 B 둘중 하나가 1이면 1
A | B | A|B |
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 1 |
③ ^ (XOR 연산자)
A나 B 둘중 하나가 1이면 1이지만 둘다 1이라면 0
A | B | A^B |
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 0 |
④ &^ (비트 클리어)
^연산 수행후 &연산을 수행한다.
2진수로 표시해보면
A &^ B 인경우 A의 비트에 1이 들어가있는자리 중 B의 비트에 1이들어가 있는자리를 0으로 만든다.
예시)
10 &^ 2
10 = 0000 1010
2 = 0000 0010
^2 = 1111 1101
10 &^ 2 = 0000 1000
(3) 시프트 연산
연산자 | 연산 | 피연산자타입 |
<< | 왼쪽 시프트 | 정수 << 양의 정수 |
>> | 오른쪽 시프트 | 정수 >> 양의 정수 |
왼쪽 시프트
기존 비트들을 왼쪽으로 밀고 비워진 공간은 0으로 채운다.
보통 1번밀면 2배, 2번밀면 4배, 3번밀면 8배지만 옆으로 밀때 1인부분이 버려진다면 늘어나지 않을수도 있다.
오른쪽 시프트
양의 정수만큼 오른쪽으로 민다
채워질 비트 : 음수면 1, 양수면 0으로 채워진다.
(4) 비교 연산자
연산자 | 설명 | 반환값 |
== | 같다 | 참이면 true 거짓이면 false |
!= | 다르다 | |
< | 작다 | |
> | 크다 | |
<= | 작거나 같다 | |
>= | 크거나 같다 |
(5) 논리 연산자
&&(and) : 양쪽모두 true이면 true를 반환한다.
||(OR) : 둘중하나만 true이면 true를 반환한다.
! (Not) : true면 false, false면 true 반환
(6) 대입 연산자
우변의 값을 좌변의 값에 복사한다.
대입연산자는 값을 반환하지 않는다.
(7) 대입연산자 응용
값교환
a,b = b,a
우변에 있는건 값으로 동작, 좌변은 공간으로 동작한다.
복합대입 연산자
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
a += 2 는 a= a+2 라는 뜻이다. 나머지도 a = a 연산자 2 로 표시된다.
증감 연산자
++, -- : go언어에서는 전위증감, 후위증감이 없다.
a++ : a+=1
그외 연산자
[] : 배열의 요소에 접근할때 사용
. : 구조체나 패키지 요소에 접근할때 사용
& : 변수의 메모리 주솟값을 반환
* : 포인터 변수가 가리키는 메모리 주소에 접근
... : 슬라이스 요소들에 접근하거나 가변 인수를 만들때 사용
: : 배열의 일부분을 집어올때 사용
<- : 채널에서 값을 빼거나 넣을때 사용
(8) 연산자 우선순위
우선순위 | 연산자 |
1 | * / % << >> & &^ |
2 | + - | ^ |
3 | == != < <= > >= |
4 | && |
5 | || |
3. 예시
(1)
package main
import (
"fmt"
)
func main (){
var x int8 = 4
var y int8 = 64
fmt.Printf("x:%08b x<<2:%08b x<<2: %d\n",x,x<<2,x<<2)
fmt.Printf("y:%08b y<<2:%08b y<<2: %d\n",y,y<<2,y<<2)
}
//출력값
//x:00000100 x<<2:00010000 x<<2: 16
//y:01000000 y<<2:00000000 y<<2: 0
Printf 에서 %08b 로 8개의 값을 2진수로 나타낸다.
x는 2칸밀어서 4배가 증가했지만 y는 1을 밀어 버려졌으므로 값이 오히려 줄어들었다.
(2)
package main
import "fmt"
func main(){
var x int8 = 16
var y int8 = -128
var z int8 = -1
var w uint8 = 128
fmt.Printf("x:%08b x>>2: %08b x>>2: %d\n",x,x>>2,x>>2)
fmt.Printf("y:%08b y>>2: %08b y>>2: %d\n",uint8(y),uint8(y>>2),uint8(y>>2))
fmt.Printf("z:%08b z>>2: %08b z>>2: %d\n",uint8(z),uint8(z>>2),uint8(z>>2))
fmt.Printf("w:%08b w>>2: %08b w>>2: %d\n",w,w>>2,w>>2)
}
//x:00010000 x>>2: 00000100 x>>2: 4
//y:10000000 y>>2: 11100000 y>>2: 224
//z:11111111 z>>2: 11111111 z>>2: 255
//w:10000000 w>>2: 00100000 w>>2: 32
y는 -128이므로 음수이기때문에 2진수로 표기하면 비트가 반대방향으로 채워진다.
y의 값이 음수이기 때문에 오른쪽으로 2번 밀고 빈공간에 1을 채워준다.
z는 -1이므로 8개의 비트에 모두 1이 들어간다.
4. 정수 오버플로우
부호있는 정수에 최대값을 넘기면 음수로 넘어가는 것을 의미한다.
package main
import "fmt"
func main() {
var x int8 = 127
fmt.Printf("%d< %d+1: %v\n", x, x, x < x+1)
fmt.Printf("x\t= %4d, %08b\n",x,x)
fmt.Printf("x+1\t= %4d, %08b\n",x+1,uint8(x+1))
}
//127< 127+1: false
//x = 127, 01111111
//x+1 = -128, 10000000
int8은 8비트의 정수이다. 8비트의 정수는 -128~127까지의 수를 표현할수 있다.
127에서 1을 더하면 128이 아닌 -128이 된다. 이는 2진수로 8개의 비트를 표기한 것을 보면 이해가 된다.
5. 실수 오차
package main
import "fmt"
func main() {
var a float64 = 0.1
var b float64 = 0.2
var c float64 = 0.3
fmt.Printf("%f + %f == %f : %v\n",a,b,c,a+b==c)
fmt.Println(a+b)
}
//0.100000 + 0.200000 == 0.300000 : false
//0.30000000000000004
실수를 표현하는 경우 계산기로 계산한 실수값과 차이가 있을수 있다.
컴퓨터는 그 실수와 가장 가까운 수를 표현한다. 그래서 0.1 + 0.2 가 0.3과 같지 않고 0.3과 근사한 값을 나타낸다.
이러한 오차는 실수계산에서 항상 발생한다. 따라서 완벽하게 오차를 극복하는 방법은 없다.
6. 실수 오차 극복
이러한 실수의 오차를 극복하기 위해 math 라는 패키지를 사용한다.
package main
import (
"fmt"
"math"
)
func equal(a,b float64) bool {
return math.Nextafter(a,b) == b
}
func main() {
var a float64 = 0.1
var b float64 = 0.2
var c float64 = 0.3
fmt.Printf("%0.18f == %0.18f : %v\n", c,a+b, equal(a+b,c))
}
//0.299999999999999989 == 0.300000000000000044 : true
math.Nextafter 는 앞의 값에서 뒤값을 향해 1비트만큼 이동한다.
따라서 true라는 값을 반환받을수 있다.
'개발 > Go' 카테고리의 다른 글
[Go] const(상수) (0) | 2022.08.11 |
---|---|
[Go] 함수(function) (0) | 2022.08.10 |
[Go] Golang fmt 패키지 (0) | 2022.08.03 |
[Go] Golang 기초 - 3 (0) | 2022.08.02 |
[Go] Golang 기초 - 2 (0) | 2022.08.02 |