『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
저자 강의