https://doonas4728.tistory.com/3
[CS] 부동소수점 오류(1)
최근에 들어간 단톡방의 사람들이 수준이 높아서 종종 대화하는 것을 읽다가 이해가 안가거나 궁금한 것을 캡쳐하던 중 재밌는 질문이 들어왔다. 100 - 64.1을 계산 했을 때 우리는 머리속으로 35.9
doonas4728.tistory.com
이전 글에서는 소수계산을 진행했을 때
왜 값이 이상하게 나오는지에 대해 다뤘다면
오늘은 근사값 오류를 개발자는 어떻게 다뤄야 하는지 알아보려고 한다.
계산 오차 해결방법

이러한 오류를 해결하면 좋지만,
우리는 이전페이지에서 리서칭하면서 정리해 본 결과
컴퓨터의 한계로 인해 오류를 해결하기보단
오류로 인한 에러를 줄이기 위해 접근하는 것이 맞는 표현인 것 같다.
.NET에서의 해결 방법
decimal 자료형을 쓰면 해결된다.
정확한 계산을 처리할 때는 효과적이지만
모든 숫자형 변수들 중에서 가장 느린 변수이기도 하다.

C#의 decimal을 제외하고 다른 방법이 있나 리처칭하던 중
백준에서 추천하는 방식을 가져와봤습니다.
https://www.acmicpc.net/blog/view/37
부동소숫점 오류
게시판에 올라오는 "이 코드는 왜 틀렸나요?" 류의 질문 중 부동소숫점 오류 때문에 틀리는 경우가 꽤 많이 보여서 간단하게 몇 가지 써봅니다. 0. 부동소숫점 오류 모든 실수를 8byte, 혹은 12~16byte
www.acmicpc.net
부동소수점 오류로 인한 애러를 줄이기 위한 주의점들
1. float보다는 double형 변수를 권장
double형 변수까지는 H/W를 통해 계산을 진행하기 때문에
많이 느려지지도 않으면서 정확성이 높아진다고 합니다.
float의 상대오차는 10^(-7)
double의 상대오차는 10^(-15)
2. 정수가 들어있는 실수형 변수를 정수로 바로 캐스팅하지 말 것
1을 double 변수로 대입하면 0.999...와 같은 숫자로 변동됩니다.
이 변수를 그대로 정수로 캐스팅하면 0으로 고정이 되는 기이한 현상이 발행합니다.
3. 비교 연산을 할 때는 등호를 사용하지 말 것
실수형 변수는 오차가 있기 때문에 같은 값을 가져야만 하는 상황임에도
다른 값일 때가 매우 많습니다.
4. 큰 수를 다룰때, 매우 작은 상수값을 사용하는 것은 위험 가능성이 존재
double의 상대오차는 10^(-15)
double형 변수에 10^(-15)을 대입하면 오차가 1의 자리에서 발생할 수 있습니다.
즉, 조건문으로 (A - B) < 1e - 6 을 진행할 때
A와 B가 10^11 크기정도라면,
A == B와 똑같은 결과가 나옵니다.
double형 변수를 가지고 넓은 범위를 이진탐색으로 돌릴 때 자주 발생하는 문제로,
100~200번 정도만 반복하거나, 상대오차가 몇 이하일 때 반복문을 빠져나오는 식으로
해결합니다.
5. 큰 수에 작은 수를 더할 때 조심할 것
double의 상대오차는 10^(-15)
double형 변수의 오차를 고려하면 1을 여러 번 넣어도 값은 변하지 않습니다.
또한, 큰수에 작은 수를 더할 때 작은 수의 정밀한 부분이 사라지기 때문에
오차가 커질 가능성이 있습니다.
보통 작은 수끼리 더한 뒤에 큰 수에 더하는 방법으로 해결이 가능하나,
이러한 특징 때문에 틀리는 문제는 극히 드뭅니다.
(연습문제: https://www.acmicpc.net/problem/1196 )
정밀도와 성능을 둘다 잡는 것은 역시 힘든 것 같다.
정밀도를 택하면 속도가 느리고
성능을 택하면 오차가 발생할 가능성이 증가한다.
가능성을 줄이고자 하는 다양한 시도를 보면서 차후에 써먹을 일이 있으면
까먹지 않고 잘 이용할 수 있으면 좋겠다.
참조
https://doonas4728.tistory.com/3
[CS] 부동소수점 오류(1)
최근에 들어간 단톡방의 사람들이 수준이 높아서 종종 대화하는 것을 읽다가 이해가 안가거나 궁금한 것을 캡쳐하던 중 재밌는 질문이 들어왔다. 100 - 64.1을 계산 했을 때 우리는 머리속으로 35.9
doonas4728.tistory.com
이전 글에서는 소수계산을 진행했을 때
왜 값이 이상하게 나오는지에 대해 다뤘다면
오늘은 근사값 오류를 개발자는 어떻게 다뤄야 하는지 알아보려고 한다.
계산 오차 해결방법

이러한 오류를 해결하면 좋지만,
우리는 이전페이지에서 리서칭하면서 정리해 본 결과
컴퓨터의 한계로 인해 오류를 해결하기보단
오류로 인한 에러를 줄이기 위해 접근하는 것이 맞는 표현인 것 같다.
.NET에서의 해결 방법
decimal 자료형을 쓰면 해결된다.
정확한 계산을 처리할 때는 효과적이지만
모든 숫자형 변수들 중에서 가장 느린 변수이기도 하다.

C#의 decimal을 제외하고 다른 방법이 있나 리처칭하던 중
백준에서 추천하는 방식을 가져와봤습니다.
https://www.acmicpc.net/blog/view/37
부동소숫점 오류
게시판에 올라오는 "이 코드는 왜 틀렸나요?" 류의 질문 중 부동소숫점 오류 때문에 틀리는 경우가 꽤 많이 보여서 간단하게 몇 가지 써봅니다. 0. 부동소숫점 오류 모든 실수를 8byte, 혹은 12~16byte
www.acmicpc.net
부동소수점 오류로 인한 애러를 줄이기 위한 주의점들
1. float보다는 double형 변수를 권장
double형 변수까지는 H/W를 통해 계산을 진행하기 때문에
많이 느려지지도 않으면서 정확성이 높아진다고 합니다.
float의 상대오차는 10^(-7)
double의 상대오차는 10^(-15)
2. 정수가 들어있는 실수형 변수를 정수로 바로 캐스팅하지 말 것
1을 double 변수로 대입하면 0.999...와 같은 숫자로 변동됩니다.
이 변수를 그대로 정수로 캐스팅하면 0으로 고정이 되는 기이한 현상이 발행합니다.
3. 비교 연산을 할 때는 등호를 사용하지 말 것
실수형 변수는 오차가 있기 때문에 같은 값을 가져야만 하는 상황임에도
다른 값일 때가 매우 많습니다.
4. 큰 수를 다룰때, 매우 작은 상수값을 사용하는 것은 위험 가능성이 존재
double의 상대오차는 10^(-15)
double형 변수에 10^(-15)을 대입하면 오차가 1의 자리에서 발생할 수 있습니다.
즉, 조건문으로 (A - B) < 1e - 6 을 진행할 때
A와 B가 10^11 크기정도라면,
A == B와 똑같은 결과가 나옵니다.
double형 변수를 가지고 넓은 범위를 이진탐색으로 돌릴 때 자주 발생하는 문제로,
100~200번 정도만 반복하거나, 상대오차가 몇 이하일 때 반복문을 빠져나오는 식으로
해결합니다.
5. 큰 수에 작은 수를 더할 때 조심할 것
double의 상대오차는 10^(-15)
double형 변수의 오차를 고려하면 1을 여러 번 넣어도 값은 변하지 않습니다.
또한, 큰수에 작은 수를 더할 때 작은 수의 정밀한 부분이 사라지기 때문에
오차가 커질 가능성이 있습니다.
보통 작은 수끼리 더한 뒤에 큰 수에 더하는 방법으로 해결이 가능하나,
이러한 특징 때문에 틀리는 문제는 극히 드뭅니다.
(연습문제: https://www.acmicpc.net/problem/1196 )
정밀도와 성능을 둘다 잡는 것은 역시 힘든 것 같다.
정밀도를 택하면 속도가 느리고
성능을 택하면 오차가 발생할 가능성이 증가한다.
가능성을 줄이고자 하는 다양한 시도를 보면서 차후에 써먹을 일이 있으면
까먹지 않고 잘 이용할 수 있으면 좋겠다.
참조