728x90
반응형
SMALL
✔ 실수의 연산
파이썬에서 실수를 연산할 때 가끔 사람의 직관에 반대되는 결과가 도출될 때가 있다.
예를들어 정수 10과 3을 나누는 연산을 해보자.
일반적으로 사람은 연산의 결과가 3.333(반올림/내림 법칙에 따른 소수점 버림)정도 혹은 3.33333333.....으로 생각할 것이다.
print(10 / 3)
>>>3.3333333333333335
하지만 파이썬에서 결과는 3.3333333333333335이다. 이는 계산의 오류일까?
또, 0.1과 0.2 두 실수의 덧셈 연산을 해보자.
사람은 0.3이라고 도출된 결과에 참이라고 대답할 것이다.
0.1 + 1.1 == 1.2
>>> False
하지만 컴퓨터는 False 결과를 도출한다. 이는 컴퓨터의 오류일까?
✔ 정수와 실수 자료형
- 파이썬에서는 정수뿐 아니라 소숫점을 포함하는 실수도 다룰 수 있다.
- 정수 데이터에는 소숫점이 없고 실수 데이터에는 소수점이 붙어 있다.
print(10) # 정수
>>> 10
print(10.0) # 실수
>>> 10.0
print(.1) # 정수부가 0인 실수는 0을 생략 가능
>>> 0.1
- 숫자 계산을 하는 경우 계산에 쓰인 숫자 중 하나라도 실수라면 계산결과는 실수가 된다.
- 나눗셈 연산의 결과는 입력에 상관없이 항상 실수로 처리
print(10 * 5) # 정수
>>> 50
print(10.0 * 5) # 실수
>>> 50.0
print(10 / 5) # 결과는 항상 실수
>>> 2.0
✔ 부동소수점 실수
- 프로그래밍 언어는 IEEE 754라는 국제표준에 따라 실수를 부동소수점 방식으로 표현
- 부동소수점 방식에서는 숫자를 정수로 된 유효숫자와 정수로 된 지수의 곱으로 표현
- 예) 십진수 부동소수점 방식에서 123.456이란 숫자는 123456 * 10^−3 이므로 123456이라는 정수 유효숫자와 −3이라는 정수 지수로 나타낼 수 있다. (정수 유효숫자: 123456, 정수 지수: -3)
파이썬에서는 유효숫자e지수 라는 방법으로 부동소수점 형태를 직접 표현한다.
123e2 # 123e2 = 123.0 x 10**2 = 12300.0
>>> 12300.0
123e-2 # 123e-2 = 123.0 x 0.01 = 1.23
>>> 1.23
123.456e-3 # # 123.456e-3 = 123.456 x 0.001 = 0.123456
>>> 0.123456
✔ 십진법과 이진법
- 컴퓨터는 십진법이 아닌 이진법을 사용
- 십진법에서는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9의 10개 숫자만 사용하고 10 이상의 수는 자리를 나타내는 숫자를 나열하여 표현
- 모든 십진법 숫자는 10의 제곱의 합으로 풀어서 나타낼 수 있다.
- 소수점이 있는 경우에는 10의 제곱승을 음수로 표현
- 이진법에서는 0, 1의 2개 숫자만 사용하고 2 이상의 수는 자리를 나타내는 숫자를 나열하여 표현
- 소수점이 있는 경우에는 2의 제곱승을 음수로 표현
파이썬에서 십진수로 이진수로 표현해보자.
- 파이썬의 bin 명령어를 사용.
- 0b는 접두사
bin(15)
>>>'0b1111' # str로 출력됨
bin(567)
>>> '0b1000110111'
✔ 부동소수점 오차
- 1보다 작은 수의 경우에 십진법으로 간단히 표현되는 수도 이진법에서는 무한개의 유효숫자를 가질 수 있음
- 예를 들어 0.1이라는 숫자는 십진수로는 간단히 표현되지만 이진수로 나타내면 다음과 같이 0011(₂)이 무한히 반복되는 실수가 됨.
- 컴퓨터에서는 하나의 숫자를 나타내기 위한 메모리 크기가 제한되어 있기 때문에 특정 소수점 이하는 생략하고 가장 비슷한 숫자로 표현함.
- 0.1은 실제로는 가장 비슷한 다음과 같은 숫자로 저장됨.
- 파이썬 콘솔이나 주피터 노트북은 REPL 인터페이스에서 값이 출력될 때 편의상 일정 소수점 이하를 생략하고 출력되기 때문에 0.1을 입력하면 0.1로 출력된다.
REPL이란?
- REPL은 Read-Eval-Print-Loop의 약자
- 애플리케이션 실행 상태에서 사용자가 입력한 명령어(소스코드)를 읽고(Read) 명령어를 평가(Eval)하고 결과를 출력(Print)한 다음 다시 입력을 기다리는 상태로 돌아가는 과정을 반복(Loop)함.
- REPL은 코드 실행 결과를 빠르게 확인하고 싶은 경우 유용함.
0.1
>>> 0.1
# 소숫점을 보고싶은 만큼 출력하기
%precision 55
>>> '%.55f'
0.1
>>> 0.1000000000000000055511151231257827021181583404541015625
# 다시 원래대로 돌아가기
%precision %r
>>> '%r'
0.1
>>> 0.1
실수의 연산 문제를 다시 생각해보자.
print(10 / 3)
>>>3.3333333333333335
0.1 + 1.1 == 1.2
>>> False
두 가지 예시에서 소숫점 55자리까지 표현하여 연산한 결과,
%precision 55 # 소숫점 55자리까지 표현
10 / 3
>>> 3.3333333333333334813630699500208720564842224121093750000
0.1 + 1.1
>>> 1.2000000000000001776356839400250464677810668945312500000
- 첫번째 문제는 소수점 17번째 자리에서 반올림한 값을 출력한 것임을 알 수 있다.
- 두번째 문제는 0.1 + 1.1 의 결과가 정확한 1.2의 값이 아닌 일정 소수점 이하를 생략하고 출력된 결과임을 알 수 있다.
✔ 실수의 비교
- round명령을 사용하여 유효숫자를 지정한 반올림을 한 후에 비교해야 함.
- round명령은 두 번째 인수로 반올림할 소수점 이하의 유효숫자의 개수를 입력.
round(0.1 + 1.1, 3) == round(1.2, 3)
>>> True
728x90
반응형
LIST
'Python > Basic' 카테고리의 다른 글
[파이썬, Python] 제어문 - 2️⃣ 반복문(1)_bool(), 대입연산자, while문, for in 문, zip함수, enumerate함수 (0) | 2023.03.08 |
---|---|
[파이썬, Python] 제어문 - 1️⃣ 조건문_ if문, 삼항 연산자, 논리 연산자 (0) | 2023.03.07 |
[파이썬, Python] 자료구조(Data Structure) - 2️⃣튜플(tuple) (0) | 2023.03.07 |
[파이썬, Python] 자료구조(Data Structure) - 1️⃣ 리스트(list) (0) | 2023.03.06 |
[파이썬, Python] 문자열(string) 다루기 - 문자열 함수, 문자열 인덱싱, 슬라이싱 (0) | 2023.03.06 |