두 개의 이진수(binary) 문자열을 입력받아, 두 수의 합을 다시 이진 문자열 형태로 반환하는 JavaScript 함수를 작성해 보겠습니다.
예를 들어 다음과 같은 두 문자열이 주어졌다고 가정해 봅시다.
const str1 = "1010"; const str2 = "1011";
이 경우 기대되는 출력 결과는 다음과 같습니다.
const output = '10101';
접근 방식
사람이 손으로 이진수 덧셈을 하는 방식과 동일하게 접근합니다. 가장 오른쪽(최하위 비트)부터 한 자리씩 더해 나가며, 합이 2 이상이 되면 올림수(carry)를 발생시켜 다음 자리 계산에 반영합니다. 두 문자열 중 하나라도 남아 있는 비트가 있거나 올림수가 존재하는 동안 이 과정을 반복하면 됩니다.
구현 예제
const str1 = "1010";
const str2 = "1011";
const addBinary = (str1, str2) => {
let carry = 0;
const res = [];
let l1 = str1.length, l2 = str2.length;
for (let i = l1 - 1, j = l2 - 1; 0 <= i || 0 <= j; --i, --j) {
let a = 0 <= i ? Number(str1[i]) : 0,
b = 0 <= j ? Number(str2[j]) : 0;
res.push((a + b + carry) % 2);
carry = 1 < a + b + carry;
};
if (carry){
res.push(1);
}
return res.reverse().join('');
};
console.log(addBinary(str1, str2));출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
10101
코드 설명
carry: 각 자리 덧셈에서 발생한 올림수를 저장하는 변수입니다.res: 계산된 각 자리의 값(0 또는 1)을 순서대로 담는 배열입니다.- for 루프는 두 문자열의 마지막 인덱스부터 시작해 왼쪽으로 한 칸씩 이동하며 반복됩니다. 어느 한쪽 문자열이 먼저 끝나면 해당 자리는 0으로 처리됩니다.
(a + b + carry) % 2가 현재 자리의 값이며,a + b + carry가 2보다 크면 올림수가 1로 설정됩니다.- 루프 종료 후에도 올림수가 남아 있다면 최상위 비트로 1을 추가합니다.
- 마지막에는 배열을
reverse()로 뒤집어 올바른 순서로 만든 뒤,join('')으로 하나의 문자열로 연결해 반환합니다.
이처럼 정수로 변환하지 않고 문자열 자체를 자리별로 처리하면, 매우 긴 이진수도 JavaScript의 숫자 범위 제한 없이 안전하게 더할 수 있다는 장점이 있습니다.