Skip to content

modulo 연산자의 의미와 활용

작성일: at 오전 01:57

Table of contents

Open Table of contents

modulo 연산

javascript에서는 % 키워드로 나머지 연산을 수행할 수 있다. 이 연산자로 구현할 수 있는 몆 가지 기능을 소개한다.

순환

Pagination을 구현할 때, 현재 페이지 인덱스 값을 기준으로 다음 인덱스 값을 계산해야 한다면?

단순하게 생각하면 index + 1로 해결할 수 있을거 같지만 마지막 인덱스에 도달하면 첫 인덱스 값을 계산할 수 없다는 문제가 생긴다.

다음 인덱스를 구하되, 마지막 인덱스에서 첫 번째 인덱스로 이동하는 코드는 아래와 같다

let arr = [1, 2, 3, 4, 5, 6];
let idx = 5;

// idx 값을 다음으로 전진하려면
idx = (idx + 1 + arr.length) % arr.length;
// 반대로 이전 값을 계산하려면
idx = (idx - 1 + arr.length) % arr.length;

연속된 숫자의 범위 계산

let month = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
let season = ? // 봄: 0, 여름: 1, 가을: 2, 겨울: 3

3, 4, 5월은 봄, 6, 7, 8월은 여름, 9, 10, 11월은 가을, 12, 1, 2월은 겨울이라고 가정한다.

우선 봄을 0으로 출력하기 위해 month 값에서 3을 빼준다. 그러면 month는 -2부터 9까지의 값으로 변한다.

이후 -2부터 9까지의 숫자를 0에서 11까지의 범위로 변환하기 위해 아래 연산을 수행한다.

// month - 3은 -2부터 9까지의 숫자를 생성한다.
(month - 3 + 12) % 12

12를 더해주면 month 값이 무조건 양수 값을 가질 수 있게 되고 이걸 다시 12로 나눈 값의 나머지를 계산하면 month는 무조건 양수가 되면서 12보다 작은 값은 그대로, 12와 같거나 큰 값은 0 이상의 숫자가 나오게 된다. (month는 이제 0에서 11 사이의 값)

각 그룹 당 3개의 요소가 포함되므로 month 값들을 3으로 나눈 다음 floor 메소드로 내림 처리해서 나눗셈의 몫을 구하면 원하는 결과를 얻을 수 있다.

month 말고 좀 더 작은 범위의 값으로 한번 더 해보자

let arr = [1, 2, 3, 4, 5, 6];

위 배열에서 1, 2, 3은 0을 출력하고 나머지 4, 5, 6은 1을 출력하는 코드를 작성해 보자.

먼저 1, 2, 3이 0이 나와야 하므로 해당 그룹의 첫 번째 값이 0이 되도록 1을 빼준다.

그럼 배열은 [0, 1, 2, 3, 4, 5] 가 된다. 이 케이스는 배열의 값이 0 이상이기 때문에 modulo 연산 없이 바로 각 그룹의 요소 개수만큼 나누어 몫을 계산하면 된다. 그러나 음수가 되는 케이스를 위해 modulo 연산을 포함하여 식을 작성하면 아래와 같다.

let arr = [1, 2, 3, 4, 5, 6];
const ARR_LEN = arr.length;

// 0 0 0 1 1 1
for(let num of arr) {
    console.log(Math.floor((num - 1 + ARR_LEN) % ARR_LEN / 3))
}

ARR_LEN를 더한 다음 바로 나누어 주었기 때문에 ARR_LEN의 역할은 요소의 값이 음수가 되지 않도록 하는 것이다.

각 그룹의 요소 개수가 3개이니까 3개씩 묶어주기 위해 3으로 나누어 나온 몫을 출력하면 완성이다.