Java - 실수자료형들

민찬홍·2023년 8월 17일

Java

목록 보기
5/31
post-thumbnail

이번에는 실수 자료형들을 다뤄볼 것이다.

		double a = 0.1, b = 0.2;

        //  ⚠️ 오차가 생김
        double c = a + b;

float: 4바이트
double: 8바이트

  • double: float보다 단순히 범위가 넓은 것이 아니라, 보다 정밀하게 표현 가능
 		//  float의 최대값과 최소값
        float fMin = -Float.MAX_VALUE;
        float fMax = Float.MAX_VALUE;

        //  double의 최대값과 최소값
        double dMin = -Double.MAX_VALUE;
        double dMax = Double.MAX_VALUE;

        //  최소 절대값
        float fAbsMin = Float.MIN_VALUE;
        double dAbsMin = Double.MIN_VALUE;

				// ⭐ double이 범위도 넓고, 정밀도도 높음 확인
        boolean bool1 = Float.MAX_VALUE < Double.MAX_VALUE;
        boolean bool2 = Float.MIN_VALUE > Double.MIN_VALUE; 
		//  최대 정밀도 테스트
        double dblNum = 0.123456789123456789;
        float fltNum = 0.123456789123456789f;

바로 위에 코드를 디버깅해보면 알 수 있듯이 float보다 double이 좀 더 세밀한 값을 출력한다.

		//  float은 뒤에 f 또는 F를 붙여 표현
        float flt1 = 3.14f;
        double dbl1 = 3.14;

        //  ⚠️ float에는 double을 담을 수 없음
        float flt2 = dbl1;
				//  반대는 가능
        double dbl2 = flt1;

자바 자체가 소수에 f가 붙어있지 않으면 double로 인식해버린다.

위에서 float에는 double을 담을 수 없다고 하였는데,

float flt2 =(float)dbl1; 

이런식으로 명시적 형변환을 해주면 담을 수는 있다. 하지만 범위나 정밀도면에서 손실되는 부분이 생긴다.

		long lng1 = 123;

       //  정수를 대입할 시 묵시적 변환
       //  💡 float(4바이트)에도 long(8바이트)의 값 담을 수 있음
       float flt3 = lng1;
       double dbl3 = lng1;

       long lng2 = Long.MAX_VALUE;

       //  ⭐ 큰 수(정확히 표현가능한 한도를 넘어서는)일 경우
       //  가능한 최대 정확도로
       float flt4 = lng2;
       double dbl4 = lng2;

실수 자료형도 큰 숫자 표현이 가능하지만, 그 숫자가 너무 크면 정확도면에서 다 표현하지는 못한다. 하지만 어지간해서는 프로그래밍 할 때 쓰는 숫자가 그렇게 크지는 않아서, 다 표현이 가능하다.

		//  💡 복합 대입 연산자와 단항 연산자 
        float fl5 = 123.45F;
        fl5 += 6.78;
        fl5++; // 🔴
        fl5++;
        fl5--;
		float flt01 = 4.124f;
        float flt02 = 4.125f;
        double dbl01 = 3.5;

        // float끼리의 연산은 float 반환
        float flt03 = flt01 + flt02;

        //  float과 double의 연산은 double 반환
        float flt04 = flt01 + dbl01; // ⚠️ 불가

        //  부동소수점 방식상 오차 자주 있음
        double dbl02 = 0.2 + 0.3f;
        double dbl03 = 0.2f * 0.7f;
        double dbl04 = 0.4 - 0.3;
        double dbl05 = 0.9f / 0.3;
        double dbl06 = 0.9 % 0.6;

        //  소수부가 2의 거듭제곱인 숫자간 연산은 오차 없음
        double dbl07 = 0.25 * 0.5f;
        double dbl08 = 0.5 + 0.25 + 0.125 + 0.0625;
        double dbl09 = 0.0625f / 0.125;
  • 부동소수점 오차 해결을 위해서는 이후 배울 BigDecimal클래스 사용
		int int1 = 5;
        float flt1 = 2f;
        double dbl1 = 3;
        double dbl2 = 7;

        //  💡 정수 자료형과 실수 자료형의 계산은 실수 반환
        int flt2 = int1 / flt1; // ⚠️ 불가
        double dbl3 = int1 / dbl1;
        double dbl4 = dbl2 / int1;

        //  💡 리터럴로 작성시 double임을 명시하려면 .0을 붙여줄 것
        double dbl5 = 5 / 2;        // 2.0
        double dbl6 = 5.0 / 2;      // 2.5
		double dbl7 = (double) 5 / 2;    // 2.5
		float fltNum = 4.567f;
        double dblNum = 5.678;

		//  💡 정수 자료형에 강제로 넣으면 소수부를 '버림'
        int int2 = (int) fltNum;  // int2 : 4
        int int3 = (int) dblNum;  // int3 : 5      

비교연산자를 사용한 비교도 가능하다.

	  int int1 = 5;
      float flt1 = 5f;
      double dbl1 = 5.0;
      double dbl2 = 7.89;

      //  💡 정수/실수간, 다른 숫자 자료형간 사용 가능
		boolean bool0 = 123 == 123F;  // true

      boolean bool1 = int1 == flt1;  // true
      boolean bool2 = flt1 == dbl1;  // true
      boolean bool3 = int1 == dbl2;  // false

      boolean bool4 = int1 > dbl2;  // false
      boolean bool5 = flt1 >= dbl2; // flase
      
      boolean bool6 = dbl1 < dbl2;  // true
profile
백엔드 개발자를 꿈꿉니다

2개의 댓글

comment-user-thumbnail
2023년 8월 17일

좋은 글 감사합니다. 자주 올게요 :)

1개의 답글