Java) 자료형과 리터럴

Wonjun Lee·2024년 4월 2일
0
  1. 자료형의 크기와 리터럴의 접두/접미사

문자형
char : 2바이트 (유니코드) 0 ~ 65535

논리형
boolean : 1바이트 (1비트로도 가능하나 최소 1바이트를 할당) true / false

정수형
byte : 1바이트 -128 ~ 127
short : 2바이트 -32768 ~ 32767
int : 4바이트 -2147483648 ~ 2147483647
long : 8바이트 (리터럴에 접미사 l또는 L을 붙여야 한다.)
약 -2의 63제곱 ~ 2의 63제곱 - 1

실수형
float : 4바이트 (리터럴에 접미사 f또는 F)

  • 단일 정밀도 (s:1, e:8, f:23) bias = 127, 7자리까지 정확히 표현

double : 8바이트

  • 두배 정밀도 (s:1, e:11, f:52) bias = 1023, 15자리까지 정확히 표현
    표현가능한 최대 수를 넘을경우 overflow로 infinity 또는 -infinity가 되고, 표현가능한 가장 정밀한 수보다 미세할 경우 underflow로 0이 된다.
100_000_000_000_000 는 int형 표현 범위를 벗어나 오버플로우가 발생한다.

float fd = 1.10; left value가 float 타입인데 right value가 1.10이므로 
문법오류가 발생한다.
char c = 's';
System.out.printf("%d", c); // 에러 발생. (int)로 형변환 필요.
  1. JVM의 피연산자 스택

    Java에서 연산을 수행할 때 피연산자 데이터를 저장하는 스택은 4Byte 크기를 가지므로, byte, short보다 int 타입을 이용하는 편이 효율적이다.

  2. 이진수 출력

    Integer.toBinaryString(); 메소드를 이용.
    정수를 받아서 이진수를 String으로 반환함.
    Float.floatToIntBits(); 메소드는 float 타입 값은 인트형으로 재해석한다. (형변환이 아니라 부동소수점 수 비트를 정수형으로 읽는다.)


  1. 기본자료형(boolean, char, 정수, 실수) 간의 형변환

boolean을 제외한 타입만 형변환이 가능하다.
부동소수점수 -> 정수로 형변환은 소수점 이하가 버려진다.

크기가 큰 정수형에서 더 작은 정수형으로 변환할 경우의 예시이다.
int 형 리터럴을 short 형으로 변환 시 -> int 형 하위 2바이트를 제외하고 모두 잘려나간다.

이런 특징으로 값손실 이 발생할 수 있다.
부호있는 수를 다룰 때 더 큰 형식으로 확장하는 경우 부호확장이 발생한다.
즉, 새로 추가된 상위 비트들을 모두 기존 비트들의 부호비트로 채운다.
이것은 2의 보수법에 따른 조치이며, 기본 컴퓨터 구조에서도 PC(프로그램 카운터)와의 주소계산을 위해 명령어 형식의 주소필드를 확장하는 연산이 일어난다.

실수형 간의 형변환 과정.
단일 정밀도에서 두배 정밀도로 변환할 때, 지수비트는 127을 빼고 1023을 더한다. 그리고 Fraction 비트는 그대로 가져오되 하위비트들을 모두 0으로 채운다.

0 1000010 11111111111111111111111
0 10000000010 111111111111111111111110000...000

두배 정밀도에서 단일 정밀도로 형변환 시에는 지수비트에서 1023을 빼고 127을 더한다. 그리고 Fraction 비트 상위에서 부터 23비트를 자르는데, 이때 24번째 비트에서 반올림한다.

정수형에서 실수형으로 형변환 과정.
정수형의 MSB인 부호비트를 그대로 가져온다. 실수형으로 변환하기 위해서는 우선 정규화 과정을 거쳐야한다.

예를 들어, 1001(9)를 부동소수점 수로 정규화 하면, 1.001 * 2^3이다.

부동소수점 수는 비트를 절약하기 위해 소수표현의 정수자리 1을 생략하고 소수점 아래 비트들만 저장한다.

이때, 실수형의 정밀도 제한으로 인해 오차가 발생할 수 있다.

int 타입의 최댓값은 10자리 십진수이지만 float 타입은 7자리만 정확히 저장할 수 있기 때문이다. 따라서 가능하면 double 타입을 이용하는 것이 안전하다.

실수형을 정수형으로 변환할 때는 자리올림이 발생하지 않는다.
변환과정은 우선 지수비트에서 기저(bias라고 한 것)을 빼고 fraction비트를 쉬프트하여 소수점 아래 비트들을 모두 제거한다.

만약 변환하는 수가 정수형 범위를 초과한다면, 오버플로우가 발생하지만
코드로 실행해 본 결과 int의 최댓값인 2147483647로 Saturation 되는 것을 볼 수 있었다.

자동 형변환
형변환은 명시하는 것이 원칙이지만 생략 가능하다.
이 경우 컴파일타임 또는 런타임에 자동적으로 형 변환이 발생하게 된다.
자동 형변환은 더 표현범위가 넓은 타입으로 변환되는 특징이 있다. 이런 과정은 보통 산술연산과 대입연산에서 발생한다.(return과 매개변수 포함)

자동 형변환 단계를 살펴보면 다음과 같다.

byte -> short,char -> int -> long -> float -> double

0개의 댓글