『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트입니다.
6장. 연산자
사실 연산자 대부분이 어느 프로그래밍 언어나 다 비슷해서 딱히 다룰 거리는 없어 보이는데, Go 언어에서 발견한 특이한 부분만 다뤄보려 한다.
XOR 연산자
특이하게도 Go에서는 비트 단위의 NOT
연산이 존재하지 않는다. 대신 XOR
을 단독 연산자로 사용하여 NOT
연산을 대체한다.
1
2
3
4
5
6
7
8
9
| package main
import "fmt"
func main() {
var uint8Max uint8 = ^uint8(0)
fmt.Printf("%b\n", uint8Max)
}
|
Bit clear 연산자
비트 연산에서 A ∧ ¬B(A AND NOT B)
를 수행하면 A에서 B에 선택된 비트들만 0으로 clear한다. Go 언어에서는 &^(AND-NOT)
을 연산자 단위로 취급, 제공한다.
1
2
3
4
5
6
7
8
9
10
11
12
| package main
import "fmt"
func main() {
var flags uint8 = 0b_11001100
var clears uint8 = 0b_01100110
fmt.Printf("%b\n", flags)
flags &^= clears
fmt.Printf("%b\n", flags)
}
|
$ ./go_bit_clear
11001100
10001000
Shift 연산자
Shift 연산이 2의 제곱에 대한 곱셈, 나눗셈 역할을 하는 것은 알고 있었다. 하지만 오른쪽 shift시 채워지는 값이 양수/음수에 따라 다르다는 것은 처음 알았다.
Go 언어만 그런 것인지, 다른 언어에서도 당연한 것인지 확인해보자.
1
2
3
4
5
6
7
8
9
10
| package main
import "fmt"
func main() {
var num1 uint8 = 0b_11001100
fmt.Printf("0x%X\n", num1 >> 2)
fmt.Printf("0x%X\n", uint8(int8(num1) >> 2))
}
|
1
2
3
4
5
6
7
8
9
| #include <stdio.h>
#include <sys/types.h>
int main(void) {
u_int8_t num1 = 0xCC;
printf("0x%X\n", num1 >> 2);
printf("0x%X\n", (u_int8_t)((int8_t)num1 >> 2));
}
|
1
2
3
4
5
6
7
8
| public class java_shr {
public static void main(String[] args) {
char num1 = 0xCC;
System.out.printf("0x%X\n", num1 >> 2);
System.out.printf("0x%X\n", ((byte)num1 >> 2));
}
}
|
$ ./go_shr
0x33
0xF3
$ ./c_shr
0x33
0xF3
$ java java_shr
0x33
0xFFFFFFF3
Go 언어만이 아니라 모든 언어에서 동일한 결과가 확인되었다.
NextAfter
컴퓨터에서 실수 연산 처리에는 오차가 수반된다. 해당 문제를 해결할 수 있도록 Go에서는 다음 비트 값의 실수를 얻는 NextAfter()
함수를 제공한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
| package main
import (
"fmt"
"math"
)
func main() {
var num1 float64 = 0.0
fmt.Printf("%g\n", num1)
fmt.Printf("%g\n", math.Nextafter(num1, 1));
}
|
$ ./go_next_after
0
5e-324
저자 강의