본문 바로가기

컴퓨터/BOJ

[BOJ](Python) 15128번 : Congruent Numbers / 부동소수점 오차

www.acmicpc.net/problem/15128

 

15128번: Congruent Numbers

Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. Each test case will consist of a single line with four integers p1, q1, p2 and q2 (1 ≤ p1,q1,p2,q2 ≤ 100,000) where p1/q1 and p2/q2 are

www.acmicpc.net

Conruent Number이란 직각삼각형에서 선분의 길이가 유리수 일 때, 면적이 양의 정수인 것을 말한다.

지금 문제에선 빗변이 유리수인지의 여부를 따지지 않는다.

 

p1, q1, p2, q2에서 빗변이 아닌 두 변의 길이는 각각 p1/q1, p2/q2이므로,

다음과 같이 나타낼 수 있으며 면적은 = (p1/q1) * (p2/q2) / 2 이다.

이를 이용한 소스 코드는 다음과 같다.

 

p_1, q_1, p_2, q_2 = map(int, input().split())
area = p_1 * p_2 / q_1 / q_2 / 2
if int(area) == area:
    print(1)
else:
    print(0)

만약 area가 정수라면 뒤의 소수점을 없애더라도 그 값이 변하지 않으므로 위의 코드와 같이 if절을 통해 정수인지 확인한다.

 

여기서 문제는 area을 계산하는 과정에서 실수 연산이 한번이라도 이루어질 경우 부동소수점 오차에 의하여 area가 정수다 하더라도 if int(area) == area: 가 성립하지 않을 수 있다.

 

예) 1 * 3 = 3.000000000000000001 처럼 나올 수 있다. 

책에선 컴퓨터 프로그램 연산 과정에서 소수점을 나타낼 때 그 근사치를 표현해주기 위한 과정에서 나타나는 오류현상이라고 한다.

 

자세한 내용은 다음을 참고하자.

python.flowdas.com/tutorial/floatingpoint.html

 

15. 부동 소수점 산술: 문제점 및 한계 — 파이썬 설명서 주석판

15. 부동 소수점 산술: 문제점 및 한계 부동 소수점 숫자는 컴퓨터 하드웨어에서 밑(base)이 2인(이진) 소수로 표현됩니다. 예를 들어, 소수 는 1/10 + 2/100 + 5/1000의 값을 가지며, 같은 방식으로 이진 �

python.flowdas.com

ko.wikipedia.org/wiki/%EB%B6%80%EB%8F%99%EC%86%8C%EC%88%98%EC%A0%90

 

부동소수점 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 초기의 전기기계식 프로그래밍 가능한 컴퓨터 Z3에는 부동소수점 산술 기능이 포함되었다. (뮌헨의 국립 독일 박물관) 부동소수점(浮動小數點, floating point) 또��

ko.wikipedia.org

따라서 이러한 부동소수점 오차를 없애기 위하여 실수 연산이 나오지 않는다면, 즉 area가 원래 정수로 표시되어야 할 값이 였다면 실수 연산을 하지 않고 정수 연산만을 진행하도록 ' *(1/2) ' 가 아닌 ' / 2 ' 와 같이 계산한다.