2장
1 역주 이는 문법 구조에 대한 설명일 뿐이다. 예를 들어 -2를 컴파일러가 구문 분석을 할 때는 -라는 단항 연산자를 2라는 상수에 적용하는 식으로 해석하긴 하지만, 바이트코드를 생성할 때는 -2라는 음수 상수를 사용한다.
2 역주 최초 설계 당시 유니코드는 65,535자만 있으면 전 세계 문자를 담기에 충분할 것으로 생각하고 설계됐다. 하지만 나중에 문자가 추가되면서 보조 문자(supplementary character)가 생겨났으며, 이 문자들의 코드포인트는 U+1000부터 U+10FFFF이므로 16비트 Char 타입에 들어갈 수 없다. 이로 인해 자바 5부터는 저수준에서는 32비트 int를 사용하는 식으로 API가 변경됐다. 다만, 기본 플레인(U+0000부터 U+FFFF)에 속하는 문자는 여전히 char 타입에 들어갈 수 있지만, 그렇지 못한 문자들은 char 하나만으로는 표현하지 못하는 경우가 생긴다. 이에 대해서는 https://www.oracle.com/technical-resources/articles/javase/supplementary.html을 읽어보라(영문).
3 역주 실수를 정수로 만들 때 수직선상에서 0 쪽으로 값이 이동한다고 생각하면 된다. 즉, 절댓값이 감소하는 방향으로 변환이 이뤄진다. 예를 들어 1.5는 1로, -1.5는 -1로 바뀐다. 한편, 여기서 어림 계산(rounding)은 10진수에서 벌어지지 않고 2진수에서 벌어진다는 점에 유의하라. 마지막 예제에서 999999995904가 나오는 이유가 바로 이 때문이다.
4 역주 혼합 연산을 허용하기는 하지만, 부동소수점 수 사이의 비교나 정수와 부동소수점 수 사이를 비교할 때는 조심해야 한다. 유효숫자 범위에 따라 미묘한 버그가 발생할 수 있다. 이에 대해 자세히 설명하는 것은 이 책의 범위를 벗어나므로 수치해석 관련 서적을 찾아보라.
5 역주 의미상으로 NaN은 수가 아니기 때문에 두 NaN이 같은 값인지를 비교할 수 없다. NaN==NaN이 항상 false가 돼야 하는 이유를 또 다른 측면에서 기술적으로 보자면, 쓰기는 NaN이라고 마치 한 값인 것처럼 썼지만 NaN을 표현하는 비트 패턴은 다양하기 때문이다. 예를 들어 32비트 Float에서 Nan은 s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx(s는 부호, x는 0 또는 1) 형태로 표현된다. Float.NaN은 이런 값 중 0x7fc00000으로 인코딩돼 있지만, 실제 부동소수점 연산에서는 다양한 NaN이 발생할 수 있다. 그래서 어떤 값이 NaN인지를 NaN 상수와 직접 비교해 알아낼 수는 없고, isNaN() 함수를 사용해야 한다.
6 역주 ‘정적으로(statically)’라는 말은 실행하기 전의 상태(주로 소스코드나 컴파일된 바이트코드)를 뜻한다. 반대로 ‘동적으로(dynamically)’라는 말은 프로그램을 실행하는 시점(즉, 런타임)을 뜻한다.
7 역주 여기서는 문자열 변환 예제를 보여주기 위해 java.util.Date를 썼지만, 시간을 다룰 때는 항상 java.time 패키지에 있는 기능을 활용하는 것이 바람직하다.