부동소수점 계산

채영민·2024년 3월 24일
0

데이터 구조_파이썬

목록 보기
23/25
post-custom-banner

📚 십진 소수점과 이진수

💡 1/3을 십진 소수점으로 나타낸 결과 :

  • 0.3333333333 이 무한으로 발생하고, 우리는 이를 보기 십게 나타내기 위해, 반올림등을 활용하고, 이 과정에서 오차가 발생하게 됨.

💡 9.625를 이진수로 변환:

  • 정수 부분 : 9 = (2^3 + 2^0) 이므로, 1001
  • 소수 부분 : 0.625는 2의 음수 제곱, 즉 (1/2)의 정수 제곱들에 합으로 구한다. 0.625 = ( 1/(2^1) + 1/(2^3) ) 이므로, 101

💡 0.1를 이진수로 변환:

  • 0.1을 소수 부분으로 나타내려고 하면, 0.1에만 가까워 질뿐, 절대 0.1로 나타낼 수 없다.
  • 즉 2진법에서 0.1은 무한소수가 된다.

📚 int 자료형

💡 int 자료형은 32개의 비트 (4 바이트) 를 사용해, 소수점이 없는 정수 데이터를 저장하기 위한 자료형

한 개의 비트에는 0 또는 1이 들어간다.

  • int 자료형의 첫번째 자리는 부호를 나타냄 (0이면 양수, 1이면 음수)
  • int 자료형은 (양수) 0부터 최대 2^31 -1 까지, (음수) 최소 -2^31 부터 -1까지 표현가능하다.
    • 여기서 0을 양수측에 넣었기 때문에 2^31에서 1을 빼주어야 한다.

📚 부동소수점(floating point)

💡 23비트를 숫자 표현에 사용할 수 있고, 소숫점의 자리도 필요한 대로 움직일 수 있으므로 고정소수점 보다 효율적으로 비트를 활용해서 다양한 숫자들을 표현할 수 있다.
💡 컴퓨터는 한정된 메모리 공간을 최대한 절약해서 소프트웨어의 많은 데이터들을 올려두고 연산해야 하기 때문에 오차가 생긴다는 단점에도, 부동소수점 자료형들로 실수들을 표현함.

🗣️ 부동 소수점은 모든 소숫점을 1.xxxx 식으로 나타낸다.

  • ex) 1001.101 -> 1.001101 로 소숫점을 앞으로 세 칸 움직여 나타낸다.
  • 부동 소수점도 맨 앞 비트는 부호를 나타내는데 사용한다.
  • 그 다음에 오는 8비트로, 소숫점이 몇 칸을 움직일지를 나타낸다. 127과의 차이를 움직일 칸의 개수로 나타내는 것이다.
    • 지수 부분에서 사용되는 8비트는 2의 거듭제곱을 나타내는데 사용되며, 이를 위해 바이어스(bias) 값 127을 사용한다.
    • ex ) 실제 지수 값이 3이라면, 이를 표현하기 위해 저장되는 값은 3 + 127 = 130이다. 반대로, 저장된 값이 130이라면, 실제 지수 값은 130 - 127 = 3
  • 나머지 23비트에는, 소숫점이 움직인 결과에서 소숫점 뒤로 오는 부분들을 채워넣는다.

💡 0.1를 부동소수점을 활용해서 나타내기

  • 0.1은 이진수에서 0.000110011 ... 로 무한소수로 나타남.
  • 이를 1.xxx로 시작하는 숫자가 되려면 소수점이 뒤로 네 칸 움직여야 한다.

📚 부동소수점 연산

💡 파이썬으로, 제곱수 판별하는 함수를 작성하고, 제출을 하니 오답이 발생하는 경우가 있었다.

import math

def solution(n):
    num = math.sqrt(n)
  
    if n == num ** 2 :
        return 1
 
    return 2

🗣️ 해당 오류가 발생한 원인 :
컴퓨터는 숫자를 비롯한 모든 데이터를 이진법으로 표현하고 처리한다. 이 과정에서 오류가 발생한 경우이다.

🗣️ 해결방안 (1):
파이썬에서 부동 소수점을 보다 더 정확하게 계산하기 위해 고안된 decimal 라이브러리 사용

import math
import decimal

def solution(n):
    num = decimal.Decimal(math.sqrt(n))
   
    if n == num ** 2 :
        return 1
   
    return 2

🗣️ 해결방안 (2):
위에서 math.sqrt(n)를 int 자료형으로 감싸서 받아주면 됨.

import math

def solution(n):
    num = int(math.sqrt(n))
  
    if n == num ** 2 :
        return 1
 
    return 2
profile
시각적인 코딩을 즐기는 개발자 지망생 채영민 입니다;
post-custom-banner

0개의 댓글