본문 바로가기



프로그래밍/JAVA

[JAVA] JAVA용 자료형 정리

정수 범위 ~

Byte : 크기 1byte, 범위 -2^7 ~ 2^7 -1 (-128 ~ 127)

다음과 같이 바이트 범위를 초과하는 데이터를 지정하면 Type mismatch: cannot convert from int to byte 오류가 나온다.

byte a = 128;

Short : 크기 2byte, 범위 -2^15 ~ 2^15-1 (-32768 ~ 32767) 

int : 크기 4byte, 범위 -2^31 ~ 2^31-1 (-2147483648 ~ 2147483647) 20억

long : 크기 8byte, 범위 -2^63 ~ 2^63-1 

- 실제 데이터를 넣을때는 값 마지막에 L을 붙여야한다. 소문자는 비슷한 문자가 많으므로, 되도록이면 대문자 L을 사용한다.

long a = 100000000L;

 

실수 범위 - 실수 계열은 정확한 비교가 어렵다. 
소숫점이하의 값이 저장될때 저장방법에 따라서 다르게 표현되기도 하므로 같은값이라고 확언할 수 없는 경우가 많다. 따라서 실수계열은 일반적인 1:1 대치 비교문에서 사용이 매우 어렵다.

Float

float : 크기 4byte, 범위 -3.4e38 ~ 3.4e38
-자바는 기본적으로 실수형 데이터를 double로 처리하기 때문에, float(즉 32비트)를 굳이 써야한다면  -실제 데이터를 넣을때는 자료형마지막에 F나 f를 넣어야 한다. 

float fst1= 1.4234F

안붙이면 자바에서는 double로 인식해버리기 때문에, 이클립스에서는 "Type mismatch: cannot convert from double to float"오류가 나타나게 된다.
만약 1.2*10^3인 지수포함된 자료를 flaot로 처리할려면 다음과 같이 입력해야 한다.

float var1 = 1.2e3F; // 실수 범위에 float를 사용하여 저장하는 코드
	System.out.println(var1);

실행해보다보니 정말로 -3.4e38입력이 가능한지 궁금해져서 입력해 보았다.

float varFloatMax =3.4e38f; //최대치 입력
	System.out.println(varFloatMax);

출력이 된다. 그런데..?

실수 영역으로만 출력이 되고 실제 10진법으로는 출력이 되지 않는다. 그럼 어느정도 데이터 영역이후는 저렇게 출력된다는 것인데 영역의 확인이 필요하다. 10진수로 쭉 출력할려면 println을 사용해서는 불가하고, 다음과 같이 printf를 사용해서 서식을 지정해야한다. 

	float varFloatMax =3.4e38f;
	System.out.printf("%f",varFloatMax); // 10진수로 출력 서식을 지정한다
	

서식을 지정하면, 10진수로 출력이 된다.

Double

double : 크기 8byte, 범위 -1.7e308 ~ 1.7e308

Double로 처리하면 float보다 처리범위가 넓어지지만 경우에 따라 부동소수연산의 성능차이가 크게 나기 때문에 적절한 trade off 지점을 찾는게 좋다.

연산을 집어넣어보다 보니 값의 처리과정이 일반적인 십진수 사칙연산과 다르게 연산되는걸 알게 되었고 비교를 위해 다음과 같은 코드를 작성하였다.

import java.math.BigDecimal;

public class ComparisonOfCalulationSizeAndAccuracy_Float_Double_BigDec {

	public static void main(String[] args) {
		float plus1_float = 0.1f;
		float plus2_float = 0.2f;
		float sumOfFloatCalcu = plus1_float+ plus2_float;
		float sD = 0.3f;
		System.out.printf("%f %n",sumOfFloatCalcu);
		if (Float.compare(sumOfFloatCalcu,sD)==0) {
			System.out.print("float 연산결과 float 0.3과 같은값 입니다."+"\n\n");
				}
		else {
			System.out.println("flaot 연산결과 0.3과 다른값 입니다.\n");
		}
		
		double plus1_double = 0.1;
		double plus2_double = 0.2;
		double sumOfDoubleCalcu = plus1_double + plus2_double;
		double double_sD = 0.3;
		System.out.println(sumOfDoubleCalcu);
		
		if (Double.compare(sumOfDoubleCalcu, double_sD)==0) {
			System.out.print("double 연산결과 double 0.3과 같은값 입니다."+"\n\n");
				}
		else {
			System.out.println("double 연산결과 double 0.3과 다른값 입니다.\n");
		}
		
		
		BigDecimal plus1_BigDecimal = BigDecimal.valueOf(0.1);
		BigDecimal plus2_BigDecimal = BigDecimal.valueOf(0.2);
		BigDecimal sumOfBigDecimal = plus1_BigDecimal.add(plus2_BigDecimal);
		BigDecimal beforesumOfBigDecimal = BigDecimal.valueOf(0.3);
		
		System.out.printf("%f %n",sumOfBigDecimal.doubleValue());
		
		if (sumOfBigDecimal.compareTo(beforesumOfBigDecimal)==0 ) {
			System.out.print("BigDecimal 연산결과 0.3과 같은값 입니다."+"\n");
				}
		else {
			System.out.println("BigDecimal 연산결과 0.3과 다른값 입니다.\n");
		}
		
		
		
	}
}

결과를 보니 어라?

출력값을 보면 일반적인 십진법 연산으로는 다 같은 값이지만, 컴퓨터에서는  서로 다른 값으로 나오는 경우가 있다. 예제에서는 float 연산과 BigDecimal을 이용한 연산의 결과값은 같으나, Double연산의 결과값은 다르게 나타난다. 이는 double이 근사치를 저장하기 때문이다. float연산도 경우에 따라 부동소수연산에 문제가 있을 경우가 있다. JAVA의 경우 이를 해결하기위한 방법으로서 BigDecimal 을 제공하는데 이는 자바에서 제공하는 최대에 가까운 정밀도를 제공하는 방법이다. 이 방법을 이용할 경우 제공되는 API가 따로 있기 때문에 기존 사칙연산요소를 사용할 수 없다. 

자바에서 실제로 최대 / 최소 범위를 코드를 짜서 조회해 볼 수 있는데 다음 코드를 입력해보자

//파일이름이 maxValueOfJavaDataType.java이다
public class maxValueOfJavaDataType {

	public static void main(String[] args) {
		System.out.println(Byte.MAX_VALUE);
		System.out.println(Short.MAX_VALUE);
		System.out.println(Integer.MAX_VALUE);
		System.out.println(Long.MAX_VALUE);
		System.out.println(Float.MAX_VALUE);
		System.out.println(Double.MAX_VALUE);
	}
}

위와 같이 최대 범위가 표시된다. 

이외의범위

boolean : 크기 적용 불가, 범위 적용 불가 참,거짓값만 가능 / 논리형 

char : 크기 2byte, 범위 0 ~ 65535 

char 와 int 연산을 바로 할 수 없다. 

char ch = 34
ch = ch + 2; // 불가능 정수값을가진 char와 int인 숫자는 같이 연산할 수 없다 
// c에서는 사용가능한 구조

중요 char code : char (32) = space, char (65) = A, char (97) = a, 대소문자는 아스키코드에서 32씩 난다.

캐스팅   : 자료형이 다를때 처리하는 방법 , 하지만 사용하지 않는게 좋다. 해당 형변환 크기보다 작을경우만 사용

형변환 실습 코드

int score = (int) 95.2;
double d = 432.1;
int v;

v = 100 + (int)d; // int를 적지 않으면 double 로 판단되어 더하기가 안된다.

System.out.println("score = " +score); // .2를 버리고 int형으로 변환된다.
System.out.println("d = " +d);
System.out.println("v = " +v);

출력 

score = 95
d = 432.1
v = 532

 

수학적으로 integer 와 float의 크다, 작다에 대한 고찰을 참고하시면 더욱 도움될것입니다.

int (integer) 와 float 자료형은 어떻게 다른가? JAVA에서... (tistory.com)

 

int (integer) 와 float 자료형은 어떻게 다른가? JAVA에서...

int 타입과 float타입의 설명을 보면, 실수타입인 float가 정수타입인 int에 비해 더 큰 수를 저장할 수 있다고 설명되어있다. 언뜻보고 지나가면 그렇지 하고 지나갈 수 있는데. 한글의 어려움이 바

fmri.tistory.com