반응형
1. 문제 번호 2720번
2. 문제 풀이
한줄 평가
- Double, Float, BigDecimal 에 대해서 좀 더 깊게 알게 되었다.
문제를 먼저 정확히 파악
- 몫과 나머지의 계산문제
- 예시) 124
- 124 ÷ 0.25 는 몫 4 나머지 0.24
- 0.24 ÷ 0.1 은 몫 2 나머지 0.04
- 0.04 ÷ 0.01 은 몫 4 나머지 0
- 예시) 124
나의 문제풀이 방식 및 순서
* 나의 다양한 학습이 우선이기 때문에 다양한 방법을 생각 *
3. 소스 인증
import java.util.*;
import java.lang.*;
import java.io.*;
// The main method must be in a class named "Main".
class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int inputCnt = Integer.parseInt(br.readLine());
StringBuilder st = new StringBuilder();
int [] intAry = {25,10,5,1};
while(inputCnt > 0){
int inputLine = Integer.parseInt(br.readLine());
for(int i = 0; i < 4; i++){
int count = inputLine / intAry[i];
st.append(count);
st.append(" ");
inputLine = (inputLine % intAry[i]);
}
st.append("\n");
inputCnt--;
}
System.out.println(st);
}
}
import java.util.*;
import java.lang.*;
import java.io.*;
// The main method must be in a class named "Main".
class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int inputCnt = Integer.parseInt(br.readLine());
StringBuilder st = new StringBuilder();
double [] intAry = {0.25, 0.10, 0.05, 0.01};
// float [] intAry = {0.25f,0.10f,0.05f,0.01f}; //f 필수!!!
while(inputCnt > 0){
/* (int / int는 정수라서 100.0 double 타입의 리터럴로 나눠줘야함 */
double inputLine = Integer.parseInt(br.readLine()) / 100.0;
for(int i = 0; i < 4; i++){
intputLine = roundFunc(inputLine, 3); //소수점 이하 3째자로 반올림
int count = (int) (inputLine / intAry[i]);
st.append(count).append(" ");
inputLine = (inputLine % intAry[i]);
}
st.append("\n");
inputCnt--;
}
System.out.println(st);
}
private static double roundFunc(double value, int places){
if(places < 0) throw new IllegalArgumentException();
BigDecimal bd = BigDecimal.valueOf(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
}
- 실패 소스코드 -
4. 추가 개념
double [] intAry = {0.25, 0.10, 0.05, 0.01};
float [] intAry = {0.25f,0.10f,0.05f,0.01f}; //f 필수!!!
- 변수의 Type이 double이여도 int ÷ int 는 정수로 계산되어진다.
double inputLine = Integer.parseInt(br.readLine()) / 100.0;
float와 double의 문제점
계산을 하는 와중에 다음과 같은 현상을 파악했다.
double a = 10.1;
double b = 10.1;
System.out.print(a+b); //20.2000000003
내가 원하는 결과값은 20.2인데 반올림 처리해서 사용해야하나?
1.24를 소수점 2째 자리에서 반올림처리해서 사용하는 경우를 예를 들어보겠다.
double inputLine = 1.24;
double [] intAry = {0.25,0.10,0.05,0.01};
for(int i = 0; i < 4; i++){
int count = (int) (inputLine / intAry[i]);
inputLine = (inputLine % intAry[i]);
}
count = 4
inputLine = 0.24
count = 2
inputLine = 0.03999999999999998
이렇게 반복적으로 몫과 나머지를 구해야 할때 원하지 않는 결과 확인했다.
그래서 BigDecimal을 알게 되었다.!!!
BigDecimal 의 출현
고정소수점과 부동소수점
고정소수점 방식
- 정수부와 소수부가 자릿수가 제한적이라서 넓은 범위의 실수르 표현하기 어렵다.
예를 들어 7.75 실수를 2진수로 변환하면 111.11이 되는데 이를 각각 지수부(정수부), 소수부로 담아 표현한다.
부동소수점 방식
- 유연한 자릿수를 가지고 있으며, 2진수로 저장되는 특성 때문에 정확한 수를 표현하지 못한다.
예를 들어 7.75 실수를 0.0775 * 10^2로 변경하여 지수부에는 2, 가수부에는 0.0775 를 담는다.
여기서 문제가 발생하는데 마지막 5에서 무한적인 소수점이 생겨난다.
double과 float는 대표적인 부동소수점 방식이다.
BigDecimal 특징
- 불변의 특징을 가지고 있어 객체 간의 연산마다 새로운 객체를 생성하여 느리다. 다만 부동소수점의 문제를 보완하기 때문에 필수적이다.
- 정수형인 unscaled value와 , 소수점 영역인 scale(32bit)
예를 들어 3.14의 경우 unscaled value는 314, scale은 2 - BigDecimal에 데이터 저장할때는 반드시 정확한 값을 넣어야 한다.
예를 들어 new BigDecimal(1.12) 이런건 안되고 new BigDecimal("1.12") 와 같이 넣어줘야 함.
기타 관련 메서드들이나 연산들은 아래 참조 블로그를 확인 바랍니다.
5. 참조 블로그
불편함을 느끼실 경우 연락 주시면 곧 바로 삭제하도록 하겠습니다.
728x90
반응형
'알고리즘(BOJ) 문제풀이' 카테고리의 다른 글
[BOJ/백준] 일반수학1_ 2292번 몇번 풀어보기 (0) | 2024.05.24 |
---|---|
[BOJ/백준] 일반수학1_ 2903번 (0) | 2024.05.23 |
[BOJ/백준] 일반수학1_ 11005번 (0) | 2024.05.22 |
[BOJ/백준] 2차원 일반수학1_ 2745번_이해할때까지 몇번보기 (0) | 2024.05.20 |
[BOJ/백준] 2차원 배열_ 2563번 (0) | 2024.05.19 |