[Chapter 2] 변수 (Variable)_5

slchoi·2022년 1월 4일
0

자바의 정석

목록 보기
7/19
post-thumbnail

'자바의 정석 3rd Edition'을 공부하며 정리한 내용입니다.

5. 형변환


5.1 형변환(캐스팅, casting)이란?

  • 서로 다른 타입간의 연산을 수행해야하는 경우 연산을 수행하기 전에 타입을 일치시켜야 함
  • 형변환(casting): 변수나 리터럴의 타입을 다른 타입으로 변환하는 것
    • ex) int 타입의 값과 float 타입의 값을 더하는 경우, 먼저 두 값을 같은 타입, 즉 둘 다 float 타입으로 변환한 다음 연산 수행

5.2 형변환 방법

  • 형변환하고자 하는 변수나 리터럴의 앞에 변환하고자 하는 타입을 괄호와 함께 붙여주기만 하면 됨

    (타입) 피연산자

    • 괄호 ()는 '캐스트 연산자' 또는 '형변환 연산자'라고 함
    • 형변환을 '캐스팅(casting)'이라고도 함
double d = 85.4;
int score = (int) d; // double 타입의 변수 d를 int 타입으로 형변환
  • 두 번째 줄의 연산 과정을 단계별로 살펴보면
   int score = (int) d;
=> int score = (int) 85.4; // 변수 d의 값을 읽어 와서 형변환
=> int score = 85;	  // 형변환의 결과인 85를 score에 저장
  • 피연산자인 변수 d의 값은 형변환 후에도 변화 없음
  • 기본형에서 boolean을 제외한 나머지 타입들은 서로 형변환 가능 but 기본형과 참조형간의 형변환은 불가능
변환수식결과
int -> char(char) 65'A'
char -> int(int) 'A'65
float -> int(int) 1.6f1
int -> float(float) 1010.0f
  • float 타입의 값을 int 타입으로 변환할 때 소수점 이하의 값은 반올림이 아닌 버림으로 처리됨

5.3 정수형간의 형변환

  • 큰 타입에서 작은 타입으로의 변환(ex. int 타입의 값을 byte 타입으로 변환)하는 경우는 크기의 차이만큼 잘려나감 => 값 손실(loss of value) 발생
  • 작은 타입에서 큰 타입으로 변환(ex. byte 타입의 값을 int 타입으로 변환)하는 경우는 저장공간의 부족으로 잘려나가는 일이 없음 => 값 손실이 발생하지 않음
    • 나머지 빈 공간은 0 또는 1로 채워짐
    • 값을 채우고 남은 빈 공간은 보통 0으로 채우지만, 변환하려는 값이 음수인 경우 빈 공간을 1로 채움. (이유: 형변환 후에도 부호를 유지할 수 있도록 하기 위해서)
  • Integer.toBinaryString(int i): 10진 정수를 2진 정수로 변환한 문자열을 출력

5.4 실수형 간의 형변환

  • 작은 타입에서 큰 타입으로 변환하는 경우 빈 공간을 0으로 채움
  • float 타입의 값을 double 타입으로 변환하는 경우
    • 지수는 float의 기저인 127을 뺀 후 double의 기저인 1023을 더해서 변환하고, 가수는 float의 가수 23자리를 채우고 남은 자리를 0으로 채움
  • double 타입에서 float 타입으로 변환하는 경우
    • 지수는 double의 기저인 1023을 뺀 후 float의 기저인 127을 더하고 가수는 double의 가수 52자리 중 23자리만 저장되고 나머지는 버려짐
    • 형변환할 때 가수의 24번째 자리에서 반올림이 발생할 수 있음. 24번째 자리의 값이 1이면, 반올림이 발생해 23번째 자리의 값이 1 증가함
  • float 타입의 범위를 넘는 값을 float로 형변환하는 경우는 '+-무한대' 또는 '+-0'을 결과로 얻음
double d = 1.0e100;	// float의 최댓값보다 큰 값을 d에 저장
float f = (float) d;	// d의 값을 float로 형변환해서 f에 저장. f는 무한대가 됨

double d = 1.0e-50;	// float의 최소값보다 작은 값을 d에 저장
float f = (float) d;	// f의 값은 0이 됨

5.5 정수형과 실수형 간의 형변환

1. 정수형을 실수형으로 변환

  • 정수를 2진수로 변환한 다음 정규화를 거쳐 실수의 저장형식으로 저장
  • 실수형의 정밀도의 제한으로 인한 오차가 발생할 수 있음
    • int의 최대값은 약 20억으로 최대 10자리의 정밀도를 요구하지만 float는 10진수로 약 7자리 정밀도만 제공하므로, int를 float로 변환할 때 정밀도 차이에 의해 오차가 발생할 수 있음
    • 10진수로 8자리 이상의 값을 실수형으로 변환할 때는 float가 아닌 double 형태로 형변환해야 오차가 발생하지 않음

2. 실수형을 정수형으로 변환

  • 실수형을 정수형으로 변환하면 소수점 이하 값은 버려짐. 정수형의 표현 형식으로 수수점 이하의 값은 표현할 수 없기 때문
    • 실수형을 정수형으로 형변환할 때 반올림이 발생하지 않음
  • 실수의 소수점을 버리고 남은 정수가 정수형의 저장범위를 넘는 경우 정수의 오버플로우가 발생한 결과를 얻음

5.6 자동 형변환

  • 컴파일러가 자동으로 생략된 형변환을 추가
float f = 1234;	// 형변환 생략. float f = (float) 1234;와 같음
  • 변수가 저장할 수 있는 값의 범위보다 더 큰 값을 저장하려는 경우에 형변환을 생략하면 에러 발생
byte b = 1000;	// 에러. byte 범위(-128~127)를 넘는 값을 저장

// 에러 메시지: incompatible types: possibly lossy conversion from int to byte
// 큰 타입에서 작은 타입으로의 형변환은 값 손실이 발생할 수 있다는 의미
  • 명시적으로 형변환을 해줬을 경우 컴파일러는 에러를 발생시키지 않음
  • 계산식에서 자주 형변환이 생략
    • 서로 다른 두 타입의 연산에서 먼저 타입을 일치시킨 다음 연산을 수행해야하므로, 연산과정에서 형변환이 자동으로 이루어짐
    • 두 타입 중 표현범위가 더 넓은 타입으로 형벼환하여 타입을 일치시킨 후 연산 수행
      • 이유: 값손실의 위험이 더 적어 올바른 결과를 얻을 확률이 높기 때문
    • 산술 변환: 연산과정에서 자동적으로 발생하는 형변환

자동 형변환 규칙

  • 자동 형변환 기준: 기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환

  • 자동 형변환이 가능한 방향

    사진 출처: https://velog.io/@yoopark/java-implicit-conversion

    • 왼쪽에서 오른쪽으로의 변환은 형변환 연산자를 생략해도 자동 형변환되며, 반대 방향으로의 변환은 반드시 형변환 연산자를 써줘야 함

형변환 정리

  1. boolean을 제외한 나머지 7개의 기본형은 서로 형변환이 가능
  2. 기본형과 참조형은 서로 형변환할 수 없음
  3. 서로 다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략 가능

Chapter 2 변수(Variable) 끝!!!

profile
예비 백엔드 개발자

0개의 댓글