일단 나머지 연산자란 두 정수를 나눌 때, 나누어 떨어지지 않은 나머지를 구하는 연산자이다.
%는 나머지 연산자 또는 (Modulo) 모듈로라고 읽는다.
식으로 보면 각각의 이름은 이렇다.
A / B = Q ... R
- A는 피제수
- B는 제수
- Q는 몫
- R은 나머지
백문이 불허일견 직접 0 ~ 30을 8로 나눈 몫과 나머지를 출력해봤다.
for (int i = 0; i <= 30; i++)
{
Console.WriteLine($"Q : {i/8}, R : {i%8}");
}
결과
Q : 0, R : 0
Q : 0, R : 1
Q : 0, R : 2
Q : 0, R : 3
Q : 0, R : 4
Q : 0, R : 5
Q : 0, R : 6
Q : 0, R : 7
Q : 1, R : 0
Q : 1, R : 1
Q : 1, R : 2
Q : 1, R : 3
Q : 1, R : 4
Q : 1, R : 5
Q : 1, R : 6
Q : 1, R : 7
Q : 2, R : 0
Q : 2, R : 1
Q : 2, R : 2
Q : 2, R : 3
Q : 2, R : 4
Q : 2, R : 5
Q : 2, R : 6
Q : 2, R : 7
Q : 3, R : 0
Q : 3, R : 1
Q : 3, R : 2
Q : 3, R : 3
Q : 3, R : 4
Q : 3, R : 5
Q : 3, R : 6
이정도면 관계성을 찾을 것이다.
몫의 경우 딱 제수만큼 수를 반복하며 1씩 증가한다.(0이 8번 출력 이후 1이 8번 출력이 반복된다.)
나머지의 경우 0 ~ (N-1)을 반복하며 출력되었다.
또한,
0 ~ 7까지는 8로 나눠 지지 않기 때문에 (피제수 = 나머지)로 출력된다.
그럼 음수는 어떻게 될까?
이번에는 수를 줄여서 0 ~ -16을 8로 나눈 몫과 나머지를 출력해봤다.
for (int i = 0; i >= -16; i--)
{
Console.WriteLine($"Q : {i/8}, R : {i%8}");
}
결과
Q : 0, R : 0
Q : 0, R : -1
Q : 0, R : -2
Q : 0, R : -3
Q : 0, R : -4
Q : 0, R : -5
Q : 0, R : -6
Q : 0, R : -7
Q : -1, R : 0
Q : -1, R : -1
Q : -1, R : -2
Q : -1, R : -3
Q : -1, R : -4
Q : -1, R : -5
Q : -1, R : -6
Q : -1, R : -7
Q : -2, R : 0
결과를 보면 위에 나온결과를 음수로 바꿨을때와 같은 결과가 나온다.
음수와 양수를 섞어서 다양한 결과를 출력해봤다.
[예 1] 5 % 2 // R : 1
[예 2] -5 % -2 // R : -1
[예 3] 5 % -2 // R : 1
[예 4] -5 % 2 // R : -1
결론을 내면 % 연산자에서 음수 처리는 다음과 같이 정의되어 있다.
X % Y 를 연산할 때 그 연산 결과의 부호는 X 의 부호를 따라간다.
즉 Y의 부호는 무시되며 오직 X가 양수이면 결과는 양수, 음수이면 결과는 음수가 된다.
연산자 자체의 기능만을 설명한 것을 본다면 어렵지 않고 별로 중요하지 않은 것처럼 보이지만, 실제로 이를 응용하여 실전에서 사용하게 될 경우에는 자신도 몰랐던 예상치 못한 결과가 나올 수도 있다는 것을 항상 염두해야 한다는 것이다.
예를 들어 배열 A에 있는 값을 반복시키면서 배열 B에 넣고 싶다면 A의 인덱스에 %연산자를 활용할 수 있다.
int[] A = new int[3] {1,2,3}; //1,2,3으로 초기화된 A 배열
int[] B = new int[10]; //초기화 되지 않은 B 배열
for(int i = 0; i < 10; i++)
{
B[i] = A[i % 3]; //0,1,2를 반복하기 때문에 A 배열의 인덱스 범위를 넘지않고 사용할 수 있다.
}
C#에서는 Random 인스턴스를 만들어서 Next()함수로 나오는 값을 정할수 있다.
매개변수로 Next(0,11)을 넣어주면 0~10 까지의 수를 랜덤으로 반환해준다.
이 Next함수에서 사용하고 있는 방식이 % 연산자이다.