자바에서 double와 float의 차이점에 대해서 알아볼려고 한다.
밑에서 볼 수 있듯이 float는 4바이트(32bit)의 수까지 표현하고, double은 8바이트(64bit)까지 수를 표현한다.
double이 좀 더 큰 숫자까지 표현을 할 수 있다
64비트 CPU의 double형 실수를 IEEE 부동 소수점 방식으로 표현하면 위와 같다.
지수부는 자릿수(크기)를 나타내는 부분
이다. 즉 가수의 어디쯤에 소수점이 있는지 나타낸다.
가수부는 실수의 실제 값을 표현하는 부분
이다.
부동 소수점 방식에서 float과 double 차이가 있다.
[ 부호 (1bit) + 지수 (8bit) + 가수 (23bit) = 32bit = 4byte ]
저장 가능한 값의 범위
(+/-)1.4E-45 ~ (+/-)3.4028235E38
범위까지 저장 및 표현이 가능하다.
자바의 실수 타입의 기본 처리는 double 타입이므로,
float 타입에 값을 저장하려면 실수 리터럴 뒤에 f 또는 F 를 붙여야 한다.
float flovar1= 3.14; // f 를 붙이지 않고 저장하면 컴파일 에러 발생!
float flovar2= 3.14f; // 3.14 실수 리터럴이 저장된다.
[ 부호 (1bit) + 지수 (11bit) + 가수 (52bit) = 64 bit = 8byte ]
저장 가능한 값의 범위
(+/-)4.9E-324 ~ (+/-)1.7976931348623157E308
double var1 = 3e5; // 300000
double var2 = 5e-3; // 0.005
double varPi = 3.14;
부동 소수점 방식은 고정 소수점 방식보다 훨씬 더 많은 범위까지 표현할 수 있지만, 항상 오차가 존재한다는 단점을 가지고 있다.
부동 소수점 방식에서 오차는 위에서 살펴본 공식에 의해 발생한다.
컴퓨터에서 실수를 가지고 수행하는 모든 연산에는 언제나 작은 오차가 존재하게 된다. 이것은 자바뿐만 아니라, 모든 프로그래밍 언어에서 발생하는 기본적인 문제이다.
public class Main {
public static void main(String[] args) {
float num1 = 123.456755684654657635432263f;
double num2 =123.456755684654657635432263;
System.out.println("float형 변수 num1 : " + num1);
System.out.println("double형 변수 num2 : " + num2);
}
}
바로 위의 예제를 보면, float형 타입이 소수 5자리
까지 정확하게 표현할 수 있으나, 그 이상은 정확하게 표현하지 못함을 보여준다.
자바의 double형 타입은 소수 14자리
까지 오차없이 표현할 수 있다. 하지만 그 이상의 소수 부분을 표현할 때는 언제나 작은 오차가 발생하는지 나타나지 않는다.
또, 아래표에서 볼 수 있듯이
나누기를 할 경우
소수점 float는 소수 7자리
까지 double은 소수 16자리
까지 표현을 한다.
예제 코드로 확인해보자.
public class FloatDoubleTest {
public static void main(String[] args){
double d = 10.0 / 3.0;
float f = 10.0f / 3.0f;
System.out.println("Double : " + d);
System.out.println("Float : " + f);
}
}
결과)
따라서 데이터 정확도를 높이려면 float보다 double이 선호된다.