오버플로우 : 변수가 담을 수 있는 값의 범위를 벗어난 데이터를 담았을 때 발생하는 현상
자료형 별 값의 최대 범위를 벗어나면 발생한 carry를 버림처리, sign bit를 반전시켜 최솟값으로 순환시키는 현상
byte로 된 데이터 자료형일 때 01111111 = +127 (맨 앞은 부호 비트) 에 +1을 해주면 어떻게 될까?
10000000= 부호 비트가 1이므로 (-)에 나머지가 0이니까 -0 일까?
아니다. 위에서 말한 대로 최솟값으로 순환한다.
즉, -128이다. 왜 그런지에 대해 알아보자.
각 자료형의 범위를 눈으로 확인하는 방법
System.out.println("byte 값의 범위 : " + Byte.MIN_VALUE + " ~ " + Byte.MAX_VALUE);
System.out.println("char 값의 범위 : " + (int)Character.MIN_VALUE + " ~ " + (int)Character.MAX_VALUE);
System.out.println("short 값의 범위 : " + Short.MIN_VALUE + " ~ " + Short.MAX_VALUE);
System.out.println("int 값의 범위 : " + Integer.MIN_VALUE + " ~ " + Integer.MAX_VALUE);
System.out.println("long 값의 범위 : " + Long.MIN_VALUE + " ~ " + Long.MAX_VALUE);
System.out.println("float 값의 범위 : " + Float.MIN_VALUE + " ~ " + Float.MAX_VALUE);
System.out.println("double 값의 범위 : " + Double.MIN_VALUE + " ~ " + Double.MAX_VALUE);
byte num1 = 126;
System.out.println("num1 + 1 = " + ++num1);
num1 + 1 = 127 // 127까지는 범위 안에 속해서 발생 X
byte num2 = 127;
System.out.println("num2 + 1 = " + ++num2);
num2 + 1 = -128 // 최대치를 넘어 오버플로우 발생
byte num3 = -128;
System.out.println("num3 - 1 = " + --num3);
num3 - 1 = 127 // 반대로 너무 작아져서 최대치로 순환하는 언더플로우 발생
간단한 해결 방법은 값의 범위를 생각해 너무 작은 자료형을 사용하지 않으면 된다.
형변환 : 변수 또는 리터럴을 다른 타입으로 변환하는 것
이전에도 다뤘던 형변환에 대한 내용이지만 간단하게 해본다.
컴파일러가 자동으로 수행해주는 타입 변환.
데이터 손실 가능성이 없는 경우 자동으로 타입을 맞춰준다.

자동 형변환이 가능하다. 데이터 손실이 없기 때문에
/* 설명. 연산 시에도 작은 자료형이 큰 자료형으로 형변환된다. */
int num1 = 10;
long num2 = 20L;
long result = num1 + num2;
System.out.println("result = " + result);
result = 30
/* 정수를 실수로 변경할 때 소수점 자리수가 없어도 실수형태로 표현이 가능하다. 이 때 데이터 손실이 없기 때문에 자동 형변환이 가능하다.
* 실제 값을 저장하는 매커니즘을 가진 것과 달리 실수형은 지수부와 가수부를 따로 나눠서 작성하기 때문에
* 바이트 크기 보다 훨씬 더 많은 값을 표현할 수 있다.
* */
//long eight = 888888888888888888888; //이것도 지동으로 형변환 된 것이다. (int 범위 벗어나면 에러 발생)
long eight = 8;
float four = eight;
System.out.println("four : " + four);
/* 따라서 실수와 정수의 연산은 실수로 연산 결과가 반환된다. */
float result3 = eight + four;
System.out.println("result3 : " + result3);
four : 8.0
result3 : 16.0
char ch1 = 'a';
int charNum = ch1;
System.out.println("charNum : " + charNum);
/* int로 type이 정해지지 않은 리터럴 형태의 정수는 char 형 변수에 기록 가능하다. (예외 케이스) */
char ch2 = 65;
System.out.println("ch2 : " + ch2);
charNum : 97
ch2 : A
형변환 (casting) 연산자를 이용한 강제적으로 수행하는 형변환
자동형변환의 조건과 정반대인 경우 강제 형변환을 사용
long lNum = 80000000000L;
int iNum = (int) lNum;
System.out.println("iNum = " + iNum);
iNum = -1604378624
큰 자료형 -> 작은 자료형 변경할 때 부호비트에 따라 -부호가 돼 이런 결과가 출력됐다.
거의 이런 경우에는 소수점을 없애고 싶을 때나 사용하는 것 정도밖에 안 된다.
어차피 소수점 없애거나 하는건 math 라이브러리의 메서드 사용하기.
float avg = 31.235f;
int floatNum = (int) avg; // 강제형변환 시
System.out.println("floatNum = " + floatNum); // 소수점이 버려진다.
floatNum = 31
char ch = 'a';
byte bnum2 = (byte) ch; //당연히 char 자료형보다 작은 크기이니 강제형변환을 해야 한다.
short snum2 = (short) ch; //같은 2byte이지만 부호비트(sign bit)로 인한 값의 범위가 다르기 때문에 강제 형변환을 해 주어야 한다.
/* 추가적으로 정수를 char 자료형에 강제 형변환해서 대입하기 테스트 */
int num1 = 97;
int num2 = -97;
char ch2 = (char) num1;
char ch3 = (char) num2; //음수도 강제 형변환 하면 대입할 수 있다.
System.out.println("ch2 : " + ch2);
System.out.println("ch3 : " + ch3);
ch2 : a
ch3 : ゚
논리형은 강제 형변환도 안 된다.