본문 바로가기
computer science

부동소수점 연산

by 개발자 쿠키 2025. 2. 19.

돈 관련 프로젝트를 진행하다 보면 1원의 오차도 발생해서는 안됩니다. 그러나 오차가 발생할 수 있습니다. 그 이유는 컴퓨터가 모든 데이터를 바이너리 형식(이진수)로 인식하고 저장하기 때문입니다. 이로 인해 부동소수점 연산에서 정밀도 손실이 발생하게 되며, 이는 일부 숫자가 정확하게 표현되지 않고 근사값으로 저장되기 때문입니다.
특히, 0.1, 0.3, 0.7과 같은 숫자들은 이진수로 변환할 수 없으며, 무한 반복되는 이진수로 변환됩니다. 컴퓨터는 이러한 값을 무한히 반복할 수 없기 때문에, 근사값을 사용하게 되고, 이로 인해 정밀도 손실이 발생하게 됩니다.
이러한 현상을 부동소수점 연산에서의 정밀도 손실이라고 하며, 이는 소수점 이하에서 오차가 발생하는 원인입니다.

0.3 (10진수) ≈ 0.010011001100110011001100... (이진수)

 

어떻게 해결해야 할까요?

 
 

해결방법 0: Decimal 모듈, python

from decimal import Decimal, getcontext

# 정밀도 설정 (예: 2자리까지 반올림)
getcontext().prec = 100  # 더 높은 정밀도 설정 가능

amount = Decimal('330000')
result = amount * Decimal('0.7')
print(result)  

 

해결방법 1: 정수 연산 사용하기, C언어

금액을 원 단위 대신 전(錢) 또는 센트와 같은 더 작은 단위로 변환하여 계산하는 방법

#include <stdio.h>

int main() {
    // 330000 원을 센트 단위로 변환 (1원 = 100센트)
    long long amount_in_cents = 330000 * 100;
    long long result_in_cents = amount_in_cents * 70 / 100;
    long long result_in_won = result_in_cents / 100; // 다시 원으로 변환
    
    printf("결과: %lld 원\\n", result_in_won); // 231000 원
    return 0;
}

 

해결 방법 2: 고정소수점 연산 사용하기

#include <stdio.h>

int main() {
    // 0.7을 100배하여 고정소수점으로 처리
    int amount = 330000;
    int result = (amount * 70) / 100; // 고정소수점 방식으로 계산
    
    printf("결과: %d 원\\n", result); // 231000 원
    return 0;
}

 

해결 방법 3: double 사용하기

float은 32비트이고, double은 64비트로 더 많은 자릿수의 값을 저장할 수 있습니다. 그러나 double이라도 여전히 일부 소수점 값은 근사값으로 저장되므로 주의가 필요합니다.

#include <stdio.h>

int main() {
    double amount = 330000.0;
    double result = amount * 0.7;
    
    // 결과는 소수점 이하 15자리 정도까지 정확하게 계산됨
    printf("결과: %.2f 원\\n", result); // 231000.00 원
    return 0;
}

'computer science' 카테고리의 다른 글

소켓 프로그래밍 완전 정복하기  (0) 2025.03.07