[이펙티브자바] item60. 정확한 답이 필요하다면 float와 double은 피하라

wally·2022년 9월 3일
  • float 와 double 타입은 과학과 공학 계산용으로 설계
  • 이진 부동소수점 연산과 넓은 범위의 수를 빠르게 정밀한 근사치로 계산하게 설계
  • 따라서 float 와 double 타입은 금융 관련 계산과는 맞지 않다.
        System.out.println(1.03 - 0.42);
        // 결과 : 0.6100000000000001
        System.out.println(1.00 - 9 * 0.10);
        // 결과 : 0.09999999999999998
		System.out.println("======== 코드 60-1 ========");
		double funds = 1.00;
		int itemsBought = 0;
		for(double price = 0.10; funds >= price; price +=0.10){
			System.out.println(price);
			funds -= price;
			itemsBought++;
		}
		System.out.println(itemsBought + "개 구입");
		System.out.println("잔돈(달러):" + funds);
		System.out.println("! 실제로 4개가 구입되어야 하지만 세번째 값이 0.3000000...4 가 되면서 3개만 구입됨");

  • 금융 계산에서는 BigDecimal, int 혹은 long 을 사용해야 한다.

BigDecimal

  • 미세한 숫자의 변동도 허용하지 않는 특히 돈과 소수점을 다룬다면 BigDecimal을 사용하셔야 한다.
  • BigDecimal은 속도는 느리지만 숫자가 어긋날 가능성을 미연에 방지할 수 있다.

BigDecimal 선언

		BigDecimal bigNumber = new BigDecimal("10000.12345");

BigDecimal 계산

		BigDecimal bigNumber1 = new BigDecimal("10000.12345");
		BigDecimal bigNumber2 = new BigDecimal("10000");

		System.out.println("덧셈(+) :" +bigNumber1.add(bigNumber2));
		System.out.println("뺄셈(-) :" +bigNumber1.subtract(bigNumber2));
		System.out.println("곱셈(*) :" +bigNumber1.multiply(bigNumber2));
		System.out.println("나눗셈(/) :" +bigNumber1.divide(bigNumber2));
		System.out.println("나머지(%) :" +bigNumber1.remainder(bigNumber2));

BigDecimal 형 변환

        BigDecimal bigDecimal = BigDecimal.valueOf(100000.12345); //double -> BigDecimal

        int int_bigNum = bigDecimal.intValue(); //BigDecimal -> int
        long long_bigNum = bigDecimal.longValue(); //BigDecimal -> long
        float float_bigNum = bigDecimal.floatValue(); //BigDecimal -> float
        double double_bigNum = bigDecimal.doubleValue(); //BigDecimal -> double
        String String_bigNum = bigDecimal.toString(); //BigDecimal -> String

BigDecimal 두 수 비교

        BigDecimal bigNumber1 = new BigDecimal("100000.12345");
        BigDecimal bigNumber2 = new BigDecimal("1000000.6789");

        //두 수 비교 compareTo 맞으면 0   틀리면 -1
        int compare = bigNumber1.compareTo(bigNumber2);
        System.out.println(compare);

BigDecimal 단점

  • 기본타입보다 쓰기가 휠씬 불편하다.
  • 훨씬 느리다
  • 단발성 계산이라면 상관으며 대안으로 int 나 long 을 쓸 수 있다.
  • int 나 long 을 쓴 다면 소수점을 직접 관리한다.
  • 혹은 소수점을 쓰지 않을 수 있도록 단위를 바꾼다.(달러 -> 센트)

BigInteger

  • long은 메모리 크기는 8byte로 표현할 수 있는 범위는 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807이다
  • 그 범위를 넘어서게 되면 모두 0으로 출력이 됩니다.
  • 돈과 관련된 개발시 항상 최악의 상황을 고려해야 하므로 무한의 정수가 들어갈 수 있는 가능성이 있다면 BigInteger이라는 클래스를 활용하는 것이 좋다
BigInteger bigNumber = new BigInteger("10000");

BigInteger 사용법

출처사이트

https://coding-factory.tistory.com/605

profile
클린코드 지향

0개의 댓글