반응형

1. 문제 번호 2720번


 

 

 

2. 문제 풀이 

 

한줄 평가

 - Double, Float, BigDecimal 에 대해서 좀 더 깊게 알게 되었다.

 

 

 

문제를 먼저 정확히 파악

 

  • 몫과 나머지의 계산문제
    1. 예시) 124
      1. 124 ÷ 0.25 는  몫 4 나머지 0.24
      2. 0.24 ÷ 0.1  은  몫 2 나머지 0.04
      3. 0.04 ÷ 0.01 은 몫 4 나머지 0

 

나의 문제풀이 방식 및 순서

 

 * 나의 다양한 학습이 우선이기 때문에 다양한 방법을 생각 *

 

 

 

 

 

 


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. 참조 블로그


 

불편함을 느끼실 경우 연락 주시면 곧 바로 삭제하도록 하겠습니다.

 


 

https://dev.gmarket.com/75

 

 

 

 

 



728x90
반응형

+ Recent posts