10진수 리터럴
1008진수 리터럴
0으로 시작함01442진수 리터럴
0b or 0B로 시작한다.0b1100100 or 0B11001000b01100100 or 0B110010016진수 리터럴
0x 또는 0X로 시작한다.0x64 or 0X640x064 or 0X064정수를 읽기 쉽도록 밑줄(underscore; _)을 숫자 사이에 삽입할 수 있다.
public class example {
public static void main(String[] args) {
//10진수 문자 삽입
System.out.println(1278_3406);
System.out.println(12_783_406);
//8진수 문자 삽입
System.out.println(07_7);
//2진수 문자삽입
System.out.println(0b110_0100);
System.out.println(0b1_1_0_0_1_0_0);
//16진수
System.out.println(0xff_aa);
}
}
정수를 저장할 메모리의 크기를 지정할 수 있다.
메모리의 크기에 따라 표현할 수 있는 정수의 크기가 다르다.
4바이트 정수
8바이트 정수
정리
0111 1111 (127)
0111 1110 (126)
0111 1101 (125)
...
0000 0001 (1)
0000 0000 (+0)
1000 0000 (-0)
1000 0001 (-1)
...
1111 1101 (-125)
1111 1110 (-126)
1111 1111 (-127)
System.out.println(0.0314e2); // 0.0314 * 10의2승 = 3.14
System.out.println(0.314e1); // 0.314 * 10의1승 = 3.14
System.out.println(31.4e-1); // 31.4 * 10의-1승 = 3.14
System.out.println(314e-2); // 314 * 10의-2승 = 3.14
float : 4바이트 크기의 부동소수점double : 8바이트 크기의 부동소수점정수처럼 메모리 크기(4바이트 또는 8바이트)에 따라 표현할 수 있는 부동소수점의 범위가 다르다.
단 IEEE 754 명세에 따라 2진수로 변환되기 때문에
정확하게 '소수점 이상 얼마까지 소수점 이하 얼마까지' 식으로 정의할 수 없다.
대신 '유효자릿수'라는 방식으로 대략적으로 값의 범위를 표현한다.
부동소수점을 저장할 때 정확하게 저장되지 않는 예
=> 32비트 float 타입(32-bit single-precision; 단정도)
[부호비트(1)][지수부(8)][가수부(23)]
=> 64비트 double 타입(64-bit double-precision; 배정도)
[부호비트(1)][지수부(11)][가수부(52)]
1) 소수점 앞의 정수 값을 2진수로 변환한다.
12(10진수)
= 1100(2진수)
2) 소수점 뒤의 값을 2진수로 변환한다.
- 변환 규칙
- 소수점을 2로 곱하여 나온 결과에서 정수 부분만을 차례대로 표기한다.
- 소수 부분이 0이거나 반복되면 계산을 멈춘다.
- 예: 0.375(10진수)
0.375 * 2 = 0.75 --> 0
0.75 * 2 = 1.5 --> 1
0.5 * 2 = 1.0 --> 1
=> 0.011(2진수)
3) 2진수 바꾼 최종 결과
12.375(10진수)
= 12(10진수) + 0.375(10진수)
= 1100(2진수) + 0.011(2진수)
= 1100.011(2진수)
= 1*2^3 + 1*2^2 + 0*2^1 + 0*2^0 + 0*2^-1 + 1*2^-2 + 1*2^-3
= 1*8 + 1*4 + 0*2 + 0*1 + 0*0.5 + 1*0.25 + 1*0.125
4) 정규화
- 소수점의 위치를 조정하여 가수부와 지수부를 분리한다.
- IEEE 754 명세는 다음과 같은 형식으로 가수부와 지수부를 나눈다.
1.x1x2x3x4...x23(2진수) * 2^e
=> 소수점 왼쪽에 1만 남도록 소수점을 이동한다.
=> 소수점 왼쪽은 무조건 1이기 때문에 저장하지 않고 버린다.
=> 따라서 소수점 오른쪽 수만 가수부에 놓는다.
즉 x1, x2 등은 가수부 1번 비트부터 23번 비트까지를 의미한다.
=> 23번 비트까지 채우지 못하면 나머지 비트는 0으로 채운다.
- 예)
1100.011(2진수)
= 1.100011(2진수) * 2^3
가수부 => 100011(2진수)
지수부 => 3 + 127(bias) = 130(10진수) = 10000010(2진수)
5) 32비트로 표현하기
[0][10000010][10001100000000000000000]
=> 0100_0001_0100_0110_0000_0000_0000_0000
=> 0x41460000
주의!
- 유효 자릿수의 부동소수점이라도 정규화할 때 2진수로 딱 떨어지지 않은 경우가 있다.
- 예) 2.127
2 => 0010
0.127 =>
0.127 * 2 = 0.254 --> 0
0.254 * 2 = 0.508 --> 0
0.508 * 2 = 1.016 --> 1
0.016 * 2 = 0.032 --> 0
0.032 * 2 = 0.064 --> 0
0.064 * 2 = 0.128 --> 0
0.128 * 2 = 0.256 --> 0
0.256 * 2 = 0.512 --> 0
0.512 * 2 = 1.024 --> 1
0.024 * 2 = 0.048 --> 0
....
이처럼 2진수로 완벽히 표현할 수 없는 수가 있다.
0.00000....1 의 오차가 있다.
그래서 부동소수점은 정수와 다르게 정확하게 2진수로 변환할 수 없는 경우가 있다.
즉 메모리에 정확하게 저장되지 않을 수 있다.