글
문제
다음은 매개변수가 홀수인지 확인하는 메서드입니다. 제대로 작동할까요?
public static boolean isOdd(int i){ return i % 2 == 1; }
풀이
이 메서드는 홀수인지 판단하는 기능을 하는데 매개변수로 음수가 들어오면 무조건 false 를 리턴합니다. 음수에도 짝수, 홀수의 개념이 있으므로 고려가 되어야 하는데 % 2 연산의 결과가 1 인지 체크하는 것은 양수만 고려한 것입니다.
a 를 int 자료형, b 를 0 이 아닌 int 자료형의 숫자라고 하면 나머지 연산자는 다음의 공식으로 표현 가능합니다.
(a / b) * b + (a % b) == a
-> a 를 b 로 나눈 몫에 b 를 곱하고, a 를 b 로 나눈 나머지를 더하면 원래 값으로 돌아간다
자바에서는 정수를 나눌 때 버림을 수행하므로 나머지 연산의 결과는 0 이 아닌 값을 반환할 때는 항상 왼쪽 피연산자의 부호와 같게 됩니다.
3 % 2 -> 1
3 % -2 -> 1
-3 % 2 -> -1
-3 % -2 -> -1
isOdd() 메서드는 나머지가 모두 양수라고 가정해서 잘못된 결과를 리턴하는 것입니다. i 가 음의 홀수인 경우 i % 2 는 1 이 아닌 -1 이므로 false 를 리턴하는데, 이 문제를 해결하려면 매개변수가 음수인 경우도 고려를 해야 합니다. 다음의 코드처럼 짝수인 경우 -> 0, 홀수인 경우 -> 0 이 아닌 정수 (양의 홀수는 1, 음의 홀수는 -1) 로 나누어 체크하면 됩니다.
public static boolean isOdd(int i){ return i % 2 != 0; }
만약 위의 코드보다 더 좋은 성능을 원한다면, 나머지 연산자보다 비트 AND 연산자 (&) 를 사용하는 것이 좋습니다.
public static boolean isOdd(int i){ return (i & 1) != 0; }
정리를 해보면, 나머지 연산자를 사용할 때는 항상 피연산자의 부호와 결과가 어떻게 나올지 생각해 보세요. 피연산자가 음수가 아닌 경우에는 쉽게 예측할 수 있지만 음수인 경우에는 예측하기 어려우니까요.
(조슈아 블로크, 닐 개프터, 『자바 퍼즐러』, 윤인성 옮김, 한빛미디어 (2014.12.04), p25~27 참고)
'9.1) 자바 퍼즐러 > CHAPTER 2. 표현식 퍼즐' 카테고리의 다른 글
4 번째 퍼즐. 초등학교 수준의 문제 (0) | 2017.07.03 |
---|---|
2 번째 퍼즐. 변화를 위한 시간 (0) | 2017.07.03 |
RECENT COMMENT