두 개의 숫자를 인수로 받아 그 차이를 반환하는 JavaScript 함수를 작성해야 합니다. 단, 빼기 연산자(-)는 사용할 수 없습니다.
접근 방식: 비트 연산 활용
빼기 연산자 없이 뺄셈을 수행하려면 비트 연산을 활용할 수 있습니다. 핵심 아이디어는 다음과 같습니다.
- XOR(
^) 연산은 올림(carry)을 고려하지 않은 자리별 덧셈(또는 뺄셈의 기초)을 수행합니다. - AND(
&) 연산 후 왼쪽 시프트(<< 1)를 하면 다음 자리로 넘어가는 올림 값을 얻을 수 있습니다.
이 과정을 재귀적으로 반복하면, 올림 값이 0이 되는 시점의 결과가 곧 최종 뺄셈 결과가 됩니다. 이 방법은 컴퓨터가 내부적으로 산술 연산을 처리하는 원리와 동일합니다.
예제 코드
const num1 = 56;
const num2 = 78;
const subtractWithoutMinus = (num1, num2) => {
// 빼는 수가 0이면 그대로 결과 반환
if (num2 === 0) {
return num1;
}
// XOR: 올림을 제외한 차이 계산
// (~num1 & num2) << 1: 빌림수(borrow) 계산 후 한 자리 왼쪽 시프트
return subtractWithoutMinus(num1 ^ num2, (~num1 & num2) << 1);
};
console.log(subtractWithoutMinus(num2, num1));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
22
동작 원리 상세 설명
위 예제에서 78 - 56 = 22를 계산하는 과정을 살펴보겠습니다.
- 첫 번째 단계:
78 ^ 56은 자리별로 XOR 연산을 수행하고,(~78 & 56) << 1은 빌림수를 계산합니다. - 재귀 호출: 빌림수가 0이 될 때까지 위 두 값을 인수로 함수를 재귀적으로 호출합니다.
- 종료 조건: 두 번째 인수(
num2)가 0이 되면 첫 번째 인수가 최종 결과이므로 이를 반환합니다.
이처럼 비트 연산만으로도 빼기 연산자 없이 정확한 뺄셈 결과를 얻을 수 있습니다. 참고로 이 기법은 면접에서 자주 등장하는 클래식한 알고리즘 문제이기도 하며, 덧셈의 경우에도 유사한 방식(XOR + carry)으로 구현할 수 있습니다.