플라즈밍
플라즈마 IT
플라즈밍
  • All (163)
    • MindSet (2)
    • Wisdom (8)
    • Book (18)
    • [Web] (6)
      • [Web]Guide (2)
      • [Web]HTML-CSS-JS (1)
      • [Web]ReactJS (0)
      • [Web]NextJS (1)
    • 퀀트주식투자 (4)
      • [리포트]포트폴리오 (4)
    • 자산배분전략 (2)
      • [리포트]자산배분전략 (1)
    • 포트폴리오 (0)
      • 발걸음 (0)
    • 개발 Note (3)
    • TipNote (5)
    • 알고리즘 (27)
      • 백준[BOJ] 오답노트 (27)
      • 백준[BOJ] 강의 정리 노트 (0)
    • etc-posts (18)
      • Unity :: C# 튜토리얼 (18)
    • Web&Know (23)
    • 끄적임 (4)
    • 세상이슈 (0)
    • Youtube 유튜브 (3)
      • Youtube 채널소개 (3)
    • 창업 Know&Idea (1)
    • Web&Dev (4)
    • 프로젝트 (6)
      • Unity5 Project (3)
      • UnrealEngine4 Project (2)
      • Web Page (1)
    • 주가차트-기술적분석 (2)
    • BlockChain (7)
    • SystemDesign (11)

인기 글

최근 글

hELLO · Designed By 정상우.
플라즈밍

플라즈마 IT

알고리즘/백준[BOJ] 오답노트

C++ 소수점 반올림 안됨. fixed가 고장났을때 - 백준 알고리즘 오답노트 2755

2019. 5. 7. 10:30
반응형

 

https://www.acmicpc.net/problem/2755

 

2755번: 이번학기 평점은 몇점?

첫째 줄에, 백준이가 이번 학기에 들은 과목 수가 주어진다. 둘째 줄부터 N개의 줄에 각 과목의 과목명, 학점, 성적이 주어진다. 과목명은 알파벳 소문자와 숫자, 그리고 밑줄 (_)로만 이루어져 있으며, 최대 100글자이고, 학점은 1보다 크거나 같고, 3보다 작거나 같은 자연수이다. 성적은 문제에 설명한 13가지 중 하나이다. 

www.acmicpc.net

#C++ 소수점 반올림 안됨. fixed가 고장났을때 

 

 

#1. 다음의 결과를 예측해 보자.

 

 cout<<fixed<<setprecision(2)<<3.27555<<"\n";
 cout<<fixed<<setprecision(2)<<3.275<<"\n";
 cout<<fixed<<setprecision(2)<<3.279<<"\n";

 

 

 

 

#2. 정상적으로 답을 낸다면 3.28 이 나와야 된다. 그러나 결과는 아니다. 

 

 

결과:


3.28
3.27
3.28

 

 

 

 

#3. 왜그런걸까? 부동소수점 오차.

 


QnA에서 다음과 같은 답을 얻었다.

 

 

해당 문제에서 예제의 경우 3.275가 답이 되어 아래 코드의 첫 번째 줄과 같이 출력하게 되면, 반올림 처리가 되는데도 불구하고 3.27로 나오기도 합니다 .

실수의 연산이기에 디버깅을 위해 찍어봐도 3.27500000으로 나오지만 실제로는 3.274999999999......의 값을 갖게 되어 2번째 줄과같이 처리를 해 주어야 하는데 이것이 의도된 것인지 궁금합니다 .


0.000000000001
1
printf("%.2f\n", ans); // 틀렸습니다
2
printf("%.2f\n", ans + 0.000000000001); // 정답


부동소수점수의 표현 방법에 대해 알아보시면 좋을 듯 합니다.

불안정성을 의도했다기보다는, 표현 범위를 확장하기 위해 오차가 발생하는 것을 감안했다고 봐야 합니다.

 

 

 

 

#4. 해결책은 

 

 

ans += 0.000000000001;

 

와 같이 처리를 해 주어야 한다.

 

 

 

//2755

#include<iostream>
#include<iomanip>

using namespace std;

int main(){

	// cout<<fixed<<setprecision(2)<<3.27555<<"\n";
	// cout<<fixed<<setprecision(2)<<3.275<<"\n";
	// cout<<fixed<<setprecision(2)<<3.279<<"\n";
	
	//입력만 잘 해
	double scoreSum = 0;
	int haczuamSum = 0;
	int n; cin>>n;
	for(int i = 1 ;i <=n; i++){
		string name; int haczuam; string score;
		cin>>name>>haczuam>>score;
		haczuamSum+=haczuam;
		
		if( score =="A+" ){ scoreSum += 4.3*(double)haczuam; }
		else if( score == "A0"){ scoreSum += 4.0*(double)haczuam;}
		else if( score == "A-"){ scoreSum += 3.7*(double)haczuam;}
		else if( score == "B+"){ scoreSum += 3.3*(double)haczuam;}
		else if( score == "B0"){ scoreSum += 3.0*(double)haczuam;}
		else if( score == "B-"){ scoreSum += 2.7*(double)haczuam;}
		else if( score == "C+"){ scoreSum += 2.3*(double)haczuam;}
		else if( score == "C0"){ scoreSum += 2.0*(double)haczuam;}
		else if( score == "C-"){ scoreSum += 1.7*(double)haczuam;}
		else if( score == "D+"){ scoreSum += 1.3*(double)haczuam;}
		else if( score == "D0"){ scoreSum += 1.0*(double)haczuam;}
		else if( score == "D-"){ scoreSum += 0.7*(double)haczuam;}
		else{ scoreSum += 0.0;}
		
	}
	double ans =  (scoreSum)/(double)haczuamSum ;
	ans += 0.000000000001;
	cout<<fixed<<setprecision(2)<<ans<<"\n";
	
	return 0;
}

/*
FB1.

	// cout<<fixed<<setprecision(2)<<3.27555<<"\n";
	// cout<<fixed<<setprecision(2)<<3.275<<"\n";
	// cout<<fixed<<setprecision(2)<<3.279<<"\n";
	

해당 문제에서 예제의 경우 3.275가 답이 되어 아래 코드의 첫 번째 줄과 같이 출력하게 되면, 반올림 처리가 되는데도 불구하고 3.27로 나오기도 합니다

실수의 연산이기에 디버깅을 위해 찍어봐도 3.27500000으로 나오지만 실제로는 3.274999999999......의 값을 갖게 되어 2번째 줄과같이 처리를 해 주어야 하는데 이것이 의도된 것인지 궁금합니다


0.000000000001
1
printf("%.2f\n", ans); // 틀렸습니다
2
printf("%.2f\n", ans + 0.000000000001); // 정답
djm03178   2달 전좋아요
부동소수점수의 표현 방법에 대해 알아보시면 좋을 듯 합니다.

불안정성을 의도했다기보다는, 표현 범위를 확장하기 위해 오차가 발생하는 것을 감안했다고 봐야 합니다.

*/

 

 

 

플라즈마 IT 블로그 - 코딩 공부 정리, IT 정보 공유

 

https://plasmacodeing.tistory.com/

 

조금이라도 도움이 되었다면 공감 및 댓글 주세요~~

 

 

 

반응형
저작자표시

'알고리즘 > 백준[BOJ] 오답노트' 카테고리의 다른 글

C++ fill 이용한 배열 초기화 1차원 배열 2차원 배열  (0) 2020.01.20
C++ 배열 인덱스 1부터 사용 하기 - 백준 알고리즘 오답노트 2011  (0) 2019.05.07
구름IDE 디버깅 하는 방법 - 백준 알고리즘 오답노트 1913  (0) 2019.05.07
알고리즘 고수의 코드를 보다. - 백준 알고리즘 오답노트 5073  (0) 2019.05.07
다이나믹 프로그래밍 오버플로어 - 백준 알고리즘 오답노트 1012  (0) 2019.05.07
    '알고리즘/백준[BOJ] 오답노트' 카테고리의 다른 글
    • C++ fill 이용한 배열 초기화 1차원 배열 2차원 배열
    • C++ 배열 인덱스 1부터 사용 하기 - 백준 알고리즘 오답노트 2011
    • 구름IDE 디버깅 하는 방법 - 백준 알고리즘 오답노트 1913
    • 알고리즘 고수의 코드를 보다. - 백준 알고리즘 오답노트 5073
    플라즈밍
    플라즈밍
    퀀트 주식투자 자산배분 데이터분석 정보 공유 프로그래밍,투자 주제의 책 강의 리뷰 노하우 전수

    티스토리툴바