[Python] 3. 연산자

Wonder_Land🛕·2022년 6월 14일
0

[Python]

목록 보기
3/12
post-thumbnail
  1. 산술/대입 연산자
  2. 관계/논리/비트 연산자
  3. 연산자 우선 순위
  4. Q&A
  5. 마치며

1 + 2 = 5라는 연산이 있습니다.
여기서 1, 2피연산자, +연산자라고 합니다.
이처럼 연산자는 피연산자들을 원하는 방향으로 움직이게 만듭니다.
프로그래밍에서도, 연산자는 피연산자들을 이용해 프로그래밍에서 원하는 방향을 만들어냅니다.

  • 연산자(Operator) : 프로그램 로직 구성의 필수 요소

1. 산술/대입 연산자

1) 산술 연산자

연산자의미
+양변의 값을 더하기
-양변의 값을 빼기
*양변의 값을 곱하기
/좌변의 값을 우변의 값으로 나누기
//좌변의 값을 우변의 값으로 나눈 몫
%좌변의 값을 우변의 값으로 나눈 나머지
**좌변의 값을 우변의 값으로 제곱

여기서 주의할 점은, /float형 결과를 반환합니다.

>>> 6/3
2.0

(1) 산술 연산자의 우선 순위

  • *, /+, -
  • ()는 우선 순위가 가장 높습니다.

(2) 문자형과 숫자형 연산

>>> a, b, c = "2", "3", 4
>>> print(a + b)	# ①문자열 "2", "3"을 연결해 문자열 "23"을 생성
23

>>> print(int(a) + int(b))	# ②문자열 "2", "3"이 정수 2, 3으로 변환
5

>>> print(b + c)	# ③문자열 "3"과 정수 4의 연산?
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    print(b + c)
TypeError: can only concatenate str (not "int") to str

위의 코드에서

+는 두 개의 문자열을 연갈한 새로운 문자열을 만드는 문자열 접합 연산의 결과입니다.

¹TypeCasting을 통해 문자열을 정수로 변환한 후 산술 연산을 실행했습니다.

문자열 접합 연산은 문자열끼리만 가능하므로, 다른 type과 사용시 TypeError가 발생합니다.
따라서 TypeCastingint(), str() 등을 통해 하나의 Type으로 유도하면 원하는 결과를 얻을 수 있겠죠?😉


2) 대입 연산자

대입 연산자는 다음과 같은 경우에 사용할 수 있습니다.

  • 변수를 선언할 때
  • 연산 결과를 변수에 저장할 때
  • 함수 변환값을 변수에 저장할 때
연산자의미
=대입(할당)
+=좌변의 변수에서 우변의 값을 더해서 좌변의 변수에 대입
-=좌변의 변수에서 우변의 값을 빼서 좌변의 변수에 대입
*=좌변의 변수에서 우변의 값을 곱해서 좌변의 변수에 대입
/=좌변의 변수에서 우변의 값으로 나누어 좌변의 변수에 대입
//=좌변의 변수에서 우변의 값으로 나눈 몫을 좌변의 변수에 대입
%=좌변의 변수에서 우변의 값으로 나눈 나머지를 좌변의 변수에 대입
**=좌변의 변수에서 우변의 값으로 제곱해서 좌변의 변수에 대입

(1) 복합 대입 연산자

>>> a = 10
>>> a += 5; print(a)
15

>>> a -= 5; print(a)
10

>>> a *= 5; print(a)
50

>>> a /= 5; print(a)	# /연산은 float형 숫자를 반환
10.0

>>> a //= 5; print(a)
2.0

>>> a %= 5; print(a)
2.0

>>> a **= 5; print(a)
32.0

2. 관계/논리/비트 연산자

1) 관계 연산자

  • 관계 연산자 : 값을 비교하는 연산
    (비교를 하는 특성때문에, 비교 연산자로 불리기도 합니다.)
연산자의미
==양변의 값이 같으면 True를 반환
!=양변의 값이 다르면 True를 반환
>좌변의 값이 우변의 값보다 크면 True를 반환
<좌변의 값이 우변의 값보다 작으면 True를 반환
>=좌변의 값이 우변의 값보다 크거나 같으면 True를 반환
<=좌변의 값이 우변의 값보다 작거나 같으면 True를 반환
>>> a = 2
>>> 1 < a < 3
True

이처럼, Python에서는 수학에서 사용하는 범위의 표현도 가능합니다.


2) 논리 연산자

논리 연산은 프로그램에서 거의 빠짐없이 사용되는 연산입니다.

  • 논리 연산자
    선택의 문제에서 특정 조건을 만족하는지를 검사하기 위한 조건식을 만들 때 사용합니다.
연산자의미
and양변의 값 모두 True일 경우에만 True 반환
or양변의 값 모두 False일 경우에만 False 반환
notTrue일 경우 False 반환, False일 경우 True 반환

(1) 부울형 변수에 대한 논리 연산 결과

ABA and BA or Bnot A
TTTTF
TFFTF
FTFTT
FFFFT

(2) 관계 연산자는 논리 연산자보다 우선 순위이다.

>>> a = 10
>>> a > 7 and a < 12
True

여기서 2번째 줄은, 7 < a < 12와 동일한 표현이 됩니다.

(3) not연산은 and/or연산보다 우선 순위이다.

>>> not a>7 and a<12
True

a>7a<12notand 순으로 연산합니다.


3) 비트 연산자

  • 비트 연산자
    코드를 작성하면서, 비트 단위의 연산이 필요할 경우 사용
연산자의미예시
&양변의 비트 값 모두 1일 경우에만 1을 반환x, y = 1,0
x & y # 0
|양변의 값 모두 0일 경우에만 0을 반환x, y = 1,0
x | y # 1
^양변의 값이 다를 경우 1, 같을 경우 0을 반환x, y = 1,0
x ^ y # 1
~비트 값이 1일 경우 0, 0일 경우 1을 반환x = 1
~ x # -2
<<좌변의 값을 우변의 값만큼 비트를 왼쪽으로 이동x = 4
x << 1 # 8
>>좌변의 값을 우변의 값만큼 비트를 오른쪽으로 이동x = 4
x << 1 # 2

ABA & BA | BA ^ B~A
111100
100110
010111
000001
>>> a = 8			#0000 1000
>>> print(~ a)		#1111 0111
-9

>>> print(a << 2)	#0010 0000
32

>>> print(a >> 2)	#0000 0010
2
  • ~²보수를 구하는 연산자로 생각해도 됩니다.
  • <<연산은 정수 값이 두 배가 됩니다.
  • >>연산은 정수 값이 반이 됩니다.

3. 연산자 우선 순위

코드를 작성하다보면 여러가지 연산자를 사용하게 됩니다.
이 때 연산자의 연산 순서 때문에, 의도하지 않은 논리적 오류가 발생할 수 있습니다.
따라서 미리 정의된 연산자의 우선순위를 알아야 합니다.

우선 순위연산자설명
1( )괄호
2**제곱
3+ - ~부호, 비트 부정
4* / // %곱하기, 나누기, 몫, 나머지
5+ -더하기, 빼기
6<< >>비트 왼쪽/오른쪽 시프트
7&비트 논리곱
8^비트 배타적 논리합
9|비트 논리합
10< <= > >= == !=
11not부정
12and논리곱
13or논리합

1) 괄호가 최우선

2) 산술 연산이 비트 연산보다 우선

3) 관계 연산이 논리 연산보다 우선


4. Q&A

1) TypeCasting(형변환)

Python에서는 연산을 할 때, 대부분의 경우 같은 type끼리만 연산을 할 수 있습니다.
따라서, 각기 다른 type인 경우에는 TypeCasting을 통해 type을 맞춰준 후 연산을 실시해야 합니다.

>>> 1 + 2.0
3.0

>>> "1" + 2.0
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    "1" + 2.0
TypeError: can only concatenate str (not "float") to str

Python에서는 여러가지 TypeCasting을 할 수 있는 함수를 지원하고 있습니다.

TypeCasting설명
int()int형으로 Casting
float()float형으로 Casting
str()str형으로 Casting
bin()2진수로 Casting
oct()8진수로 Casting
hex()16진수로 Casting
>>> int(2.0)
2
>>> float(2)
2.0
>>> str(2)
'2'
>>> bin(2)
'0b10'
>>> oct(2)
'0o2'
>>> hex(2)
'0x2'

TypeCasing은 정수, 실수, 문자형뿐만 아니라 복합형에도 가능합니다.

TypeCasting설명
tuple()tuple형으로 Casting
list()list형으로 Casting
set()set형으로 Casting
dict()dict형으로 Casting
  • dictionary형은 key와 value가 한 쌍으로 된 경우에만, Casting할 수 있습니다.
    그래서 help(dict())을 실행해보면,
    dict(mapping) -> new dictionary initialized from a mapping object's | (key, value) pairs과 같은 설명을 얻을 수 있습니다.
>>> tuple([1,2,3])
(1, 2, 3)
>>> list((1,2,3))
[1, 2, 3]
>>> set((1,2,3))
{1, 2, 3}
>>> dict( [ ("key1", "val1"),("key2", "val2") ] )
{'key1': 'val1', 'key2': 'val2'}

또한 특정 문자를 유니코드로 Casting할 수 있습니다.

TypeCasting설명
ord()문자를 유니코드 값으로 Casting
chr()유니코드 값을 문자로 Casting
>>> ord('가')
44032
>>> chr(44032)
'가'

2. 보수(Complement)

  • 보수(Complement) : 보충을 해주는 수
    ex) 1에 대한 10의 보수 : 9
    ex) 4에 대한 15의 보수 : 11
    ex) 2에 대한 1의 보수 : 1

먼저 n진수에서는, n의 보수(n-1)의 보수가 사용됩니다.

  • n의 보수에서는,
    임의의 수 a와, a에 대한 n의 보수 b가 있다고 할 때, a + b = (n의 제곱수)가 되어야 하죠.
  • (n-1)의 보수에서는,
    임의의 수 aa에 대한 (n-1)의 보수 b가 있다고 할 때, a + b = (n의 제곱수) - 1가 되어야 합니다.

무슨 말인지 헷갈릴 수 있는데요, 예시로 보시면 금방 이해가 될 거에요😊

10진수 → 10의 보수, 9의 보수가 사용됨

  • 10의 보수에서, 4에 대한 10의 보수는 6이 됩니다.
    왜냐하면, 44에 대한 10의 보수의 합이 10의 제곱수인 10을 만들어야 하기 때문이죠.
  • 9의 보수에서, 4에 대한 9의 보수는 5가 됩니다.
    왜냐하면, 44에 대한 9의 보수의 합이 (10의 제곱수 - 1)인 9(10-1)을 만들어야 하기 때문이죠.

여기서 한 특성을 알 수 있는데요

  1. (n-1)의 보수는, 임의의 수 a각 자릿수를 (n-1)에서 빼주면 구할 수 있습니다.
    ex) 10진수 12의 9의 보수 : 99 - 12 = 87

  2. n의 보수(n-1)의 보수 + 1을 하면 구할 수 있습니다.
    ex) 10진수 12의 10의 보수
    1) 12 + (12의 10의 보수) = 100 (10의 제곱수) ∴ 88
    2) 10진수 12의 9의 보수인 87 + 1 인 88
    와 같이 2가지 방법으로 구할 수 있습니다.

  3. 즉, n의 보수는 각 자릿수의 값을 (n-1)로 빼준 값(n-1에 대한 보수)에 +1을 하면 되겠죠?

컴퓨터는 2진수를 이용하고 있으므로 2진수에 대해서도 살펴볼까요?

2진수에서는 2의 보수1의 보수가 사용되겠죠?
10진수의 9는, 2진수에서 1001입니다.
2진수 1001의 1의 보수는 0110입니다.
1111 - 1001 = 0110(각 자릿수의 값을 (n-1)인 1에서 빼줌→비트 뒤집기)
2진수 1001의 2의 보수는 0111입니다.
1111 - 1001 + 1 = 0111(1의 보수 + 1, 즉 각 자릿수의 값을 (n-1)에서 빼준 후 + 1)

  • 2진수에서 1의 보수는 쉽게 구할 수 있는데요,
    각 비트를 반대로 뒤집으면 됩니다.
  • 2의 보수는 반대로 뒤집은 1의 보수에 +1만 하면 되죠.
    ex) 1001의 1의 보수는 0110이고, 2의 보수는 +1을 하면 0111이 되겠죠.

그런데 갑자기 보수라는 개념이 왜 등장한 걸까요?🤔
바로 컴퓨터에서 음수를 표현하기 위해서 입니다.
컴퓨터는 기본적으로 뺄셈 연산을 하지 못하기 때문에, 양수를 2의 보수를 사용해 음수로 만들어준 후 덧셈 연산을 진행합니다.

예를 들어, 3 - 2 = 1이라는 연산에서 컴퓨터는 뺄셈 연산을 못하기 때문에 2의 2의 보수를 구해 3 + (-2) = 1과 같이 연산을 하게 되죠.

실제 연산에서 본다면,
1. 3 - 2는 2진수로 변환하면 0011 - 0010이 되겠죠.
2. 컴퓨터는 뺄셈 연산을 못하기 때문에 2진수 2의 2의 보수를 덧셈 연산으로 변환합니다.
3. 2진수 2의 보수를 구하기 위해서는 1의 보수를 구해야 합니다. 1111 - 0010 = 1101이 되겠죠.
(비트 뒤집기를 해도 된답니다.)
4. 1의 보수에 +1을 하면 2의 보수가 됩니다. 1101 + 0001 = 1110.
즉, 2진수 2의 2의 보수는 1110입니다.
5. 결과적으로 컴퓨터는 0011 + 1110이라는 연산을 하게 되는 것이죠. 해당 연산의 결과는 10001이 되는데 4비트 표현에서 구했기 때문에 최상위 비트인 1은 무시합니다. 따라서 00011이 됩니다.

사실 컴퓨터에서 음수를 표현하는 방법으로는

1. 부호 절댓값 방법

(부호 비트를 제외한 수를 양수로 읽기, 부호 비트에 따라 부호를 결정하는 방식)

2. 1의 보수 방법

3. 2의 보수 방법

로 3가지가 있습니다.
주로 정수나 고정 소숫점에서는 2의 보수 방법을 사용하고, 부동 소수점에서 유효숫자는 부호 절댓값 방법을 사용한다고 합니다.


5. 마치며

오늘은 프로그래밍의 연산에 기본이 되는 연산자들에 대해 알아봤습니다..
연산자들에 의해 이루어지는 연산은 프로그래밍에 있어 필수적이고 가장 기본이 되는 역할이기 때문에 중요하게 알아야 합니다.
마지막으로 다루었던 내용인 보수는 컴퓨터의 숫자 표현에 있어 굉장히 중요한 내용입니다.
추후에 컴퓨터가 숫자를 표현하는 방법에 대해서도 다룰 기회가 있을 것 같네요.😊

[Reference] : 위 글은 다음 내용을 참고, 인용하여 만들어졌습니다.

profile
아무것도 모르는 컴공 학생의 Wonder_Land

0개의 댓글