[C++] 부동 소수점 오차에 의한 오류

유빈·2024년 3월 16일
0
post-thumbnail

2-1학기 전공수업 - 객체지향프로그래밍 - 과제 2주차


1. 문제

객지프 - Assignment 01 - 13번


2. (double) 형변환


#include <iostream>

using namespace std;

int main() {
    int cnt = 0;

    for (int x = 0; x <= 100; x++) {
        for (int y = 0; y <= 100; y++) {
            if (y >= (1/3)*x && y <= (2/3)*x && x*x+y*y <= 10000) {
                cnt++;
            }
        }
    } 
    cout << cnt << endl;

    return 0;
}

// Output : 101

처음 문제를 풀 때는 위와 같이 풀었다.
그런데 정답인 1362에 택도 없는 답인 101이 출력되었다.


// 1
y >= (1/3)*x && y <= (2/3)*x && x*x+y*y <= 10000
// 2
y >= 0 && y <= 0 && x*x+y*y <= 10000

조건 1에 따르면, 1/3에서 1과 3이 int형이므로 1/3 = 0이 된다.
따라서, 조건 1과 조건 2는 같다고 볼 수 있다.

그러므로 모든 y는 0이고, x는 0부터 100까지이므로 101이 출력되게 된다.


#include <iostream>

using namespace std;

int main() {
    int cnt = 0;

    for (int x = 0; x <= 100; x++) {
        for (int y = 0; y <= 100; y++) {
            if (y >= ((double) 1/3)*x && y <= ((double) 2/3)*x && x*x+y*y <= 10000) {
                cnt++;
            }
        }
    } 
    cout << cnt << endl;

    return 0;
}

// Output : 1335

위와 같이 1/32/3(double) 형변환해주면 0이 아닌 부동 소수점의 값인 0.333... , 0.666... 으로 계산된다.


3. 부동소수점 오차

GPT 선생님의 도움을 받아보자!

➡️ 즉, 부동 소수점 연산에 의한 오차가 발생한 것이다.


#include <iostream>

using namespace std;

int main() {
    int cnt = 0;

    for (int x = 0; x <= 100; x++) {
        for (int y = 0; y <= 100; y++) {
            if (3*y >= x && 3*y <= 2*x && x*x+y*y <= 10000) {
                cnt++;
            }
        }
    } 
    cout << cnt << endl;

    return 0;
}
if (3*y >= x && 3*y <= 2*x && x*x+y*y <= 10000)

위와 같이 바꿔준다면, 부동 소수점의 연산을 하지 않기 때문에 오차에 의한 오류가 발생하지 않는다.


허허.. 부동소수점 오차... 😵🥹

profile
🌱

0개의 댓글