자바 실수 자료형
목차
자바의 정수형과 문자 자료형을 둘러 봤다면 그 다음은 실수 자료형을 알아 볼 차례입니다.
내부적으로 정수형은 이진법과 2의 보수를 사용하고 문자 자료형은 2바이트 유니코드 시스템을 사용한다고 배웠습니다. 한글 11,172자도 2바이트 정수에 매핑하여 표현이 가능합니다.
다음은 실수 자료형인데, 실수형은 내부적으로 정수와는 다른 방식으로 표현됩니다. 실수형은 지수와 가수를 나눈 부동 소수점 방식으로 표현합니다.
1.0 x 10의-2승 –> 0.01
부동 소수점이란 소수점이 부유한다 float 는 뜻에서 유래했습니다. 컴퓨터 내부에 실수를 저장하기 위해서는 0과 1의 바이너리로 표현해야 하는데 이것을 실제 구현하는 것은 좀 지루합니다. IEEE 754 에는 32비트 단정도와 64비트 배정도를 사용해서 변환한다는 정도로 이해해 두면 좋을 것 같습니다.
대부분의 자바 프로그래밍 교재에서는 IEEE 754 변환같이 어려운 내용은 잘 나와있지 않습니다. 공학을 배우는 학생들이 배우는 내용이고요. 관심있는 분은 인터넷에 검색해도 자료가 많습니다.
컴퓨터 프로그래밍을 설계하는데 있어서는 부동소수점은 정수에 비해 연산 시간이 길다는 단점이 있는 반면 과학적 표기법을 사용해서 표현범위가 넓다는 장점이 있습니다.
실수 자료형의 범위
클래스를 사용해서 범위를 파악해 보겠습니다.
package com; public class Main { public static void main(String[] args) { System.out.println("가장 작은 float값 : " + Float.MIN_VALUE); System.out.println("가장 작은 float값(음수) : " + -Float.MAX_VALUE); System.out.println("가장 큰 float값(양수) : " + Float.MAX_VALUE); System.out.println("가장 작은 double값 : " +Double.MIN_VALUE); System.out.println("가장 작은 double값(음수) : " +-Double.MAX_VALUE); System.out.println("가장 큰 double값(양수) : " +Double.MAX_VALUE); } }
가장 작은 float값 : 1.4E-45 가장 작은 float값(음수) : -3.4028235E38 가장 큰 float값(양수) : 3.4028235E38 가장 작은 double값 : 4.9E-324 가장 작은 double값(음수) : -1.7976931348623157E308 가장 큰 double값(양수) : 1.7976931348623157E308
MIN_VALUE의 경우 가장 작은 소수 범위를 말합니다. 1.4의 10의-45승이면 분모가 0이 45개인 엄청난 숫자네요. float 는 E38 (10의 38승) 까지 범위의 값이 표현가능하고, double 은 10의 308승까지 표현할 수 있으니 뭐 엄청나죠?
같은 비트를 가지고 범위를 늘리기 위해 복잡한 내부를 구현했습니다. 때문에 속도가 느리기 때문에 정수를 써도 되는 일에 굳이 부동소수점을 사용하지 않도록 합니다.
속도의 문제로 정수를 소수처럼 사용하는 경우도 많습니다. 정수 1000을 가지고 연산을 하다가 스크린에 출력할 때만 10.00 이렇게 표기하면 정수를 소수처럼 사용하는 것도 가능합니다.
실수 자료형 정확도 문제
또 하나는 정확도 문제가 있는 경우 정수형을 사용하기도 합니다. 미화 달러 표시의 경우 보통 1.99 이것을 소수로 연산하다 보면 소수점이 어긋나는 경우가 생기는데 이것은 0.01 달러 라도 돈이기 때문에 심각한 문제가 발생합니다.
double dVar; dVar = 0.1 * 3 / 3; System.out.println(dVar);
0.10000000000000002
자바로 위의 코드를 실행하면 이해할 수 없는 결과가 나옵니다. 만약 금융거래에서 이런식으로 연산을 반복하면 몇초내에 수백만 달러의 미화가 생성될 수 있습니다. 이걸 해결하지 못하면 금융사고로 이어질 것입니다.
또 하나의 예를 보겠습니다.
public static void main(String[] args) { double myDouble = 0; for (int i = 1; i <= 100; i++) { myDouble += 0.1; } System.out.println(myDouble); }
9.99999999999998
0.1을 100번 더하면 10이 되야하는데 소수점이 모자랍니다. 1000번 10000번 이상 더하면 더 이상한 결과를 볼 수 있습니다. float과 double 은 정밀도에서 근본적인 문제가 있는 자료형입니다.
이는 자바의 문제가 아니라 부동 소수점인 double 과 float 저장방식의 근본적인 결함이기 때문에 부동 소수점 방식을 사용하는 다른 프로그래밍 언어에서도 마찬가지입니다.
때문에 Java 에서는 화폐를 다루는 별도의 클래스와 API가 있습니다. 정밀도가 아주 중요한 경우 부동 소수점을 쓰기 전에 체크할 필요가 있습니다.
그럼에도 불구하고 왜 사용하느냐? 의문을 가질 수 있는데 64비트로 10의 308승까지 표현하는 것은 정수보다 수십배나 넓은 범위를 커버할 수 있기 때문입니다.
트레이드오프가 있으니까 변수를 만들 때 어떤 자료형을 사용할지 대략 생각을 해두는 것이 좋습니다.
부동소수점 기준 double 형
자바의 부동 소수점의 기준은 double 형입니다.
실수 리터럴 1은 int 형이라고 했죠? 64비트 long 형은 접미사 L을 붙여줘야 합니다.
실수 리터럴 1.0 이것은 double 로 저장합니다. 32비트 float 형은 접미사 F를 붙여줍니다.
float 는 다음과 같이 정의하지 않으면 오류가 납니다.
float myFloat = 10.0F;
정수형은 32bit int 형이 기준, 실수형은 64bit 부동소수점 double 이 기준이 됩니다.
자바는 언뜻 자유롭게 보일 때도 있지만 엄격한 타입 검사를 한다는 것에 주의합니다.
요약
자바 실수 자료형을 알아봤습니다.
정수와 문자형 보다 어려운 데이터형으로 볼 수 있습니다. 조금 더 생각해보면 컴퓨터는 0과1의 디지털 방식인데 아날로그인 실수를 억지로 컴퓨터에 넣다보니 복잡한 방법을 사용할 수 밖에 없습니다.
실수에 대하여 더 깊이 알고 싶다면 부동 소수점 IEEE 754 변환과 2의 보수법에 대한 자료를 찾아 보는 것도 좋습니다.
외부참조문서
자바 튜토리얼 (2-3) 자바의 변수 (자바 실수 자료형, 부동소수점 방식)
한글 인코딩의 이해 2편: 유니코드와 Java를 이용한 한글 처리 (naver.com)
자바 실수 자료형 API
Float (Java Platform SE 7 ) (oracle.com)
Double (Java Platform SE 7 ) (oracle.com)
안녕하세요^^
좋은 글 감사합니다.
재밌게 보던중 어느순간 다음학습 버튼이 안눌리는 것 같네요..
저는 목차를 통해 보았지만 혹시 모르실까봐 노파심에 적어보았습니다.ㅎㅎㅎ
안녕하세요! 수정해주셔서 링크 수정했습니다~
부족한 내용을 좋게 읽어주셔서 감사합니당~~