2014년 9월 1일 월요일

Java 변수(5-정수형과 실수형)

2.4 정수형 - byte, short, int, long


정수형에는 모두 4개의 자료형이 있으며 저장할 수 잇는 값의 범위가 서로 다르다 크기순으로 나열하면 다음과 같습니다. 크기는 byte입니다.(1byte = 8bit)

byte(1) < short(2) < int(4) < long(8)

byte부터 long까지 2배씩 증가한다. 이중에서 기본 자료형(default data type)은 int이다.
변수에 저장하려는 정수값의 범위에 따라 선택하면 된다. byte나 short보다는 int를 사용하는 것이 좋다.
 정수형 변수의 선언과 초기화는 다음과 같습니다.

byte b = 1;                                                                                                                   
short s = 2;                                                                                                                  
int c = 10                                                                                                                     
long d = 1000000000L(long 타입의 리터럴에는 접미사 L을 붙여야 한다.)                            

위의 문장은 10진수를 변수에 저장한 것이다.
 16진수 혹은 8진수를 표현된 정수 또한 변수에 저장할 수 있는데, 16진수라는 것을 알려주기 위하여 리터널 앞에 접두사'0x' 또는 'OX'를, 8진수의 경우에는 '0'을 붙인다.

int OctNumber = 010;  //8진수 10, 10진수로는 8                                                               
int HexNumber = 0x10; // 16진수 10, 10진수로는 16                                                         

정수형은 0과 1로 이루어진 2진수로 저징이 됩니다. 가장 쉬운 예로 byte의 경우 크기가 1byte이고 1byte는 8bit이므로 byte형은 0/0/0/0/0/0/0/0이 됩니다. 각 자리에는 0또는 1만이 허용이 되기 때문에 1byte로 2^8이 됩니다.(256가지의 값을 표현 할 수 있습니다.)
 모든 정수형은 0을 포함한 양수와 음수를 저장하는 값의 범위로 하기 때문에, 8자리 중에서 왼쪽에서 첫 번째 자리를 부호자리로 사용하기 때문에 실제 표현하는 값의 자리수는 7개, 즉 ±2^7개가 되는 것이다. 따라서 byte형 변수가 가질 수 있는 값의 범위는 -128~`127(-2^7~2^7-1)이 된다.

정수형의 범위한계에 대한 예제

package overflow;

public class overflow {

public static void main(String[] args) {
byte a = 0; //byte형 변수 b를 선언하고 0으로 초기화
int b = 0; //int형 변수를 i로 선언하고 0으로 초기화

for(int x=0;x<=270;x++){ //x가 0에서 시작하여 270까지 증가하는 반복문
System.out.println(a++); //a를 하나씩 증가시키면서 출력
System.out.print('\t'); //줄 바꿈이 아니라 tap
System.out.println(b++); //b를 하나씩 증가시키면서 출력
}

}

}

실행결과
0         0                               -3      253
1         1                               -2      254
2         2                               -1      255
....                                         0      256
125     125                              1      257
126     126                              2      258 
127     127                              .....
-128     128                            12     268
-127     129                            13     269
....                                        14     270

위에 보는 것과 같이 byte형으로 표현할 수 잇는 값의 범위는 -128~127(-2^7~2^7-1)이다. 따라서 위의 예제를 보면 byte와 int가 0으로 시작하여 1씩 증가를 하여 270까지 가야하는 코드이지만 byte의 경우는 저장 범위를 넘어섰기 때문에 오버플로우(overflow)가 발생하게 된다. 오류는 없지만 예상한 결과가 나오지 않게 된다는 것이다. 따라서 원하는 결과를 얻기 위해서는 정수형의 저장할 수 있는 범위를 고려하여 선택해야 한다. 
어떤 기계판이 있다고 하자, 그 기계판이 세 자리 숫자로 표현이 된다고 하자, 그리고 000부터 999까지 밖에 표현하지 못하므로 999가 넘어가면 다시 000으로 돌아오게 된다. byte의 경우 최소 -128(최소값)에서 시작하여 127(최대값)을 넘어가면 다시 -127부터 시작한다. 즉, 256을 주기로 값이 계속 반복된다. 또 다른 정수형 타입인 short, int, long 역시 저장할 수 있는 값의 범위를 넘는 경우 위의 예제와 같이 된다. 변수의 범위를 넘는 값으로 초기화하는 것은 허용하지 않는다.(byte a = 128; // 에러가 발생합니다. 즉 초과 범위 설정안 안됩니다.)

2.5 실수형 - float, double

실수형은 크게 float와 double, 두 가지가 있으며 실수를 저장하는데 사용이 됩니다. float는 4byte 그리고 double은 8byte로 정수형 int와 long형과 같지만 다른 저장 방식 때문에 정수형 보다 저장범위가 훨씬 더 큰 범위의 값을 표현할 수 있습니다.
 실수는 정수와 달리 부동소수점(floating-point) 방식으로 저장을 하는데 부동소수점 방식은 실수를 ±a*10^n의 형태로 표현합니다. a는 가수이고 n은 지수입니다. 단 가수 a는 0=<a<1 범위의 실수이어야 합니다.
예를들어 3.14를 부동소수점 방식으로 표현하면 0.314*10^1이며 가수는 0.314이고 지수는 1이 됩니다.

float : 1 + 8 + 23 = 32bit = 42bit
S(1)      E(8)        M(23)

double : 1 + 11 + 52 = 64bit = 8byte
S(1)      E(11)       M(52)

(숫자)는 할당된 자리수 입니다. 가수(M)를 표현하는데 있어서 float에 비해 double이 약 두 배의 자리수가 배정되어 있기 때문에 double이 float보다 정밀도(소수점 이하의 자리수)가 더 높은 값을 표현할 수 있다는 것을 알 수 있습니다.
float는 가수를 10진수로 7자리 정보를 표현할 수 있기 때문에 더 높은 정밀도를 요구하는 작업을 할 때는 double을 사용해야 합니다.

float와 double의 정밀도에 관한 예제

public class Presicion {

public static void main(String[] args) {

float f = 1.2345678901234567890f;
double d = 1.2345678901234567890;
float f2 = 0.100000001f;
double d2 = 0.100000001;
double d3 = 0.1000000000000001;

System.out.println(f);
System.out.println(d);
System.out.println(f2);
System.out.println(d2);
System.out.println(d3);

}

}

실행결과

1.2345679 <- 끝자리가 반올림되었다.
1.2345678901234567
0.1 <- 0.100000001f
0.100000001
0.1000000000000001

float형 변수 f2에 0.100000001f를 저장하였는데도 0.1이 출력되는 이유는 float가 표현할 수 잇는 가수의 자리수(정밀도)를 넘어서는 것이기 때문입니다. 같은 값을 저장한 double형 변수 d2는 가수의 자리수 float보다 약 2배정도 많기 때문에 값을 더 정확히 표현할 수 있습니다.
 float형 리터럴에는 접미사 f가 사용되고 double형 리터널에는 d가 사용이 됩니다.
정수형에는 int가 기본 자료형인 것 처럼 실수형에서는 double이 기본 자료형이다 그래서 접미사를 생략하면 double형 리터널로 간주한다.
float pi = 3.14                                                                                                               
위와 같이 문장을 써버리면 실수형에서는 double이 기본 자료형이기 때문에 float접미사를 생략하면 double형 리터럴로 간주되기 때문에 오류가 난다. 

댓글 없음:

댓글 쓰기