ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BigDecimal (feat. 소수점 계산)
    Java/Basic 2019. 3. 26. 11:45
    반응형

     자바에서 float,double 로 계산을 해본사람들이 있다면 종종 경험하는 것들이 있다. 두가지 타입이 가진 정밀도 문제로 인하여 내가 원하는 값이 아니라 근사치가 나오는경우를 볼수 있다. 

     소수점 두자리 끼리 더했는데 갑자기 0.4699999999999 이런식으로 뒤에 99999 가 붙는 경우가 생긴다. 소수점 정밀도에 한계가 있어서 값이 유실 되는경우 발생한다. 보통 integer 형태를 많이 사용하기 때문에 잘 느끼지 못하지만 소수점을 복잡하게 계산하다보면 값은 점점 산으로 간다. 그래서 자바에서 제공하는 변수타입(?) 중 정밀하게 표현할수 있는 유일한 방법인 BigDecimal 을 사용해야 한다. 

     BigDecimal 의 단점은 딱 두가지다 . 느리다 , 사용법이 기본 변수타입보단 좀 불편하다. 

    일단 느린건 어쩔수 없다. 내부적으로 수를 십진수 형태로 저장 하고 연산에 대한 정밀도를 보장할수있는 기능을 수행하기 때문에 일반적으로 기본변수타입끼리의 연산보단 한단계 작업을 더 거치기 때문이다. 

     그리고 사용법이 불편하단건 선언 문을 보면 바로 이해가 간다. 

    BigDecimal sum = new BigDecimal("1.0");

       BigDecimal sum = new BigDecimal("2.2"); 
       sum = sum.add(temp);
    sum = sum.subtract(temp);
    sum = sum.multiply(temp);


    //반올림 정책 명시가 가능함.

    sum = sum.divide(temp,RoundingMode.HALF_EVEN); sum = sum.divide(temp,MathContext.DECIMAL32));

    기본제공되는 변수타입과는 다르게 String 과 동일한 클래스형 변수이다. 그렇기 때문에 BigDecimal 로 선언된 변수는 다양한 기능을 제공한다. 기본적인 더하기 빼기 곱하기 나누기는 물론 API 문서를 찾아보면 많은 기능들이 사용가능하도록 되있다. 

    "0.0" 은 클래스 변수이기때문에 변수 생성시 값을 지정해서 생성할수도 있다. 저렇게 지정한 두 BigDecimal 변수끼라 연산이 용이하다.

    개인적으로 아주 좋았던건 저 변수에서 .toString() 을 사용이 가능하다는것이다. 별도로 String 으로 변환하는 작업이 필요 없다. 

    웹페이지상에서 문자로 보여줘야하는경우가 많은데 그럴때 유용하게 사용이 가능할거 같다. 

     그리고 초기화시에 String 값 형태로 넣어아 한다. . double 값으로 입력해도 되지만 같은 값을 문자로 넣을때와 다르게 의도치 않은 값이 할당 될수도 있기때문에 String 형태로 설정하는게 좋다. 

    BigDecimal.ZERO
    
    BigDecimal.ONE
    
    BigDecimal.TEN

    BigDecimal 은 상수값도 정의 되있다. 기본상수값을 명시하기에 좋을것같다. 그저 1,0,10 이렇게 표현하기보다는 고정값을 할당 해야한다면 명시적으로 사용해도 좋을거 같다. 


    BigDecimal sum = new BigDecimal("1.0");

    BigDecimal sum = new BigDecimal("2.2"); 

    // 소수점 맨끝까지 동일해야 true

    sum.equals(temp);

    // 소수점 맨끝 0을 무시하고 동일하면 0 적으면 -1 많으면 1

    sum.compareTo(temp);

    비교 연산이 된다는건 생각보다 여러가지로 많은 활용이 가능할거 같다. if 문은 항상 써야 하고 이런값들을 쉽게 비교가 된다면 로직 구성상 이점이 있을거 같다. 


    구글링을 하다보니 Kotlin 에서 BigDecimal  하는 방법이 더 간단하다고 한다. 아직 자세히 찾아 보진 않았지만 성능이 좀 느려도 정확성이 보장되야 하는 경우라면 BigDecimal 을 사용하는것을 고려 해보는것이 좋을거 같다. 


    반응형

    'Java > Basic' 카테고리의 다른 글

    Logback 시간과 system 시간이 다를때...  (0) 2019.06.25
    JVM( GC) 이해하기  (0) 2019.04.26
    [java] Http get,post 통신  (0) 2019.01.28
    [java]날짜 더하기, 빼기 , 구하기  (0) 2019.01.28
Designed by Tistory.