[Go언어] 3. 연산자

Jermaine ·2023년 8월 17일
0

Go언어

목록 보기
4/9

Chapter 6 연산자


chapter 6에서는 Go 언어에서 사용되는 연산자의 종류와 이에 대한 설명이 있다. 크게 아래의 주제로 설명한다.
1. 산술 연산자
2. 비교 연산자
3. 논리 연산자
4. 대입 연산자
5. 연산자 우선 순위


산술 연산자

사칙연산과 나머지연산

연산자연산피연산자 타입
+덧셈정수, 실수, 복소수, 문자열
-뺄셈정수, 실수, 복소수
*곱셈정수, 실수, 복소수
/나눗셈정수, 실수, 복소수
%나머지정수

비트연산

연산자연산피연산자 타입
&AND 비트연산정수
|OR 비트연산정수
^XOR 비트연산정수,
&^비트 클리어연산정수

시프트연산

연산자연산피연산자 타입
<<AND 비트연산정수
>>OR 비트연산정수

다른 언어와 비슷하게 산술 연산자를 사용하면 된다. 산술 연산자는 크게 구분하면 사칙연산과 나머지연산, 비트 연산, 시프트 연산 이 있다. Go언어에서는 시프트 연산을 제외한 모든 산술 연사자의 각 항의 타입은 같아야한다. 강타입 언어이기 때문에, 상이한 타입의 피연산자의 연산은 타입변환을 강제로 수행하여, 타입을 맞춰줘야한다. 또한, 산술연산의 결과 값 또한, 피연산자와의 타입과 동일하다.
다. 1. 산술 연산자 2. 비교 연산자 3. 논리 연산자 4. 대입 연산자 5. 연산자 우선 순 ***

  • 사칙연산자와 나머지연산자은 우리가 다 아는 산술연산 이다.
  • 비트 연산자는 정수를 비트로 표현했을 때 나타나는 비트를 단위로 연산을 수행하는 것이다. 정수만 피연산자로 지원하며 각 비트마다 연산을 수행한다.
    • & 연산은 두 피연산 비트가 모두 1일 때, 1을 반환하고, 나머지는 0을 반환한다.
    • | 연산은 두 피연산 비트 둘 중 하나라도 1일 때, 1을 반환하고, 나머지는 0을 반환한다.
    • ^ 연산은 두 피연산 비트가 서로 다르면 1을 반환하고, 나머지는 0을 반환한다.
      • 단항 연산자로 사용되면( ex 34^), 그저 비트를 반전 시키는 결과가 나온다.
    • &^ (비트 클리어)연산은 특정 비트를 0으로 변경하는 연산자다. 우항의 1이 표시된 자리를 좌항의 숫자를 0으로 바꾸는 연산을 수행한다.
      • 10 &^2를 하면 0000 1010 &^ 0000 0010 = 0000 1000 이 된다.
  • 시프트 연산자는 우항의 숫자만큼 좌항의 숫자를 비트를 오른쪽 혹은 왼쪽으로 미는 연산을 수행한다.
    • >> 연산은 우항만큼 좌항의 숫자를 오른쪽으로 밀고, 밀린 자리의 비트는 그대로 버려지고, 왼쪽의 비어있는 비트에는 음수면 1, 양수면 0이 채워진다.
    • << 연산은 우항만큼 좌항의 숫자를 왼쪽으로 밀고, 밀린 자리의 비트는 그대로 버려지고, 오른쪽의 비어있는 비트에는 0으로 채워진다.

비교 연산자

비교 연산자는 피연산자의 비교를 통해 연산의 값이 참이면 true, 거짓이면 false를 반환한다. 비교 연산자는 흐름제어문(if, for, while, etc) 주로 흐름에 대한 진행 여부를 판단하고자 할 때, 사용된다.

연산자연산피연산자 타입
==같다true / false
!=다르다true / false
<작다true / false
>크다true / false
<=작거나 같다true / false
>=크거나 같다true / false

너무 간단한 로직이지만, 부호가 있는 숫자를 비교할 때, 정수 오퍼플로우, 정수 언더플로우, 실수끼리 비교
이 세 가지 경우에 대해서 조심해야한다.

  1. 정수 오퍼플로우: 현재 정수에 대한 연산이 해당 정수의 Max 범위를 넘어갔을 때, 음수가 되는 현상
  2. 정수 언더플로우: 현재 정수에 대한 연산이 해당 정수의 Min 범위를 넘어갔을 때, 양수가 되는 현상
  3. 실수끼리 비교 : 실수는 mantissaexponent를 기반으로 한 표현 방식으로 인하여, 정확한 값이 아니라, 표현 범위내에서 가장 가까운 근사치로 표현하기 때문에, 실제 값과 표현치의 오차가 있는 경우가 있다. 그렇기 때문에, 비교 연산 시 예기치 못한 오류가 발생할 수 있다.

실수 오차

math 패키지 안에는 func Nextafter(x,y float64) (r float64) 함수가 존재하는데, 이 함수는 float64 인자를 두 개를 전달받아 x에서 y를 향해 1비트만 조정한 값을 반환한다. 즉, 가장 작은 오차만큼을 y를 향해서 조정을 한 값을 반환하는 함수다. 이를 이용하여 아래와 같이 미세한 실수 오차를 감안한 비교연산을 수행할 수 있다.

package main

import (
	"fmt"
	"math"
)

func equal(a float64, b float64) bool {
	return math.Nextafter(a, b) == b
}

func main() {
	var (
		a float64 = 0.1
		b float64 = 0.2
		c float64 = 0.3
	)

	fmt.Printf("%0.18f + %0.18f = %0.18f\n", a, b, a+b)
	fmt.Printf("%0.18f == %0.18f : %v\n", c, a+b, equal(a+b, c))

	a = 0.0000000000004
	b = 0.0000000000002
	c = 0.0000000000007

	fmt.Printf("%g == %g : %v\n", c, a+b, equal(a+b, c))
}

논리 연산자

논리 연산자boolean 피연산자 두 개(!는 단항)에 대하여 논리 연산을 수행하고, 결과가 참이면 true, 거짓이면 false를 반환한다.

연산자연산피연산자 타입
&&AND두 피연산자 모두 true라면, true 아니라면 false
||OR두 피연산자 중 하나라도 true라면, true 아니라면 false
!NOT연산자가 true라면 false, false라면 true

대입 연산자

대입 연산자=는 우항을 좌항에 복사하여 대입하는 연산자로, 이를 기반으로 하여 복합 대입 연산자, 증감 연산자를 지원한다.

연산자설명
a = bb의 값을 a에 복사
a += ba = a + b
a -= ba = a - b
a /= ba = a / b
a *= ba = a * b
a %= ba = a % b
a++a = a + 1
a--a = a + 1
a, b = b, aa, b를 스왑
a, b = c, dac를, bd를 복사

그 외 연산자...

연산자설명
[]배열 원소 접근
.객체, 패키지 요소 접근
&변수의 메모리 주솟값을 반환
*포인턴 변수가 가리키는 메모리 주소에 접근
...슬라이스 요소들에 접근하거나 가변 인수를 만들 때 사용
:배열의 일부분을 집어올 때 사용
<-채널에서 값을 빼거나 넣을 때 사용

연산자 우선 순위

우리가 학교에서 배운것 처럼 모든 연산에는 순서가 있다. 우선순위가 같으면 좌측부터 우측으로 연산된다.
아무리 우선순위가 있어도, 가독성을 위해서 괄호로 그냥 묶어주는 것이 나에게도, 같이 일하는 팀원에게도 좋다. 진짜로..

우선순위연산자
5* / % << >> & &^
4+ - | , ^
3== != < <= > >=
2&&
1||

비교적 너무 당연한 말들이어서, 덧붙여서 설명할 건 크게 없고, 제발 여러 연산자가 많다면, 괄호를 붙이자.

profile
저메인 주도 개발

0개의 댓글