C언어에서는 정수 나눗셈을 하면 그 값을 Ceil 시킨다는 것이었다.
이 부분에서 수학적으로 나머지가 항상 0보다 크거나 같다는 생각을 가지고 있었고, 정수 나눗셈이 몫을 구하는 연산이라고 생각하고 있어서 이상하다고 생각했다.
그러나 자세히 알아보니 수학적으로 나머지가 항상 0일 필요는 없다. 더욱이 각 언어마다 나머지를 어떻게 정의하느냐에 따라서 몫과 그 나머지 계산이 다 달라지게 된다.
일단, C언어에서 정수 나눗셈의 나머지는 피제수와 같은 부호를 가지게 된다.(C99 전에는 어느 것을 선택해도 가능했다.)
그리고 나눗셈의 결과는 몫을 나타내게 된다.
예를 들면 아래와 같은 코드는 그 아래와 같은 결과를 나타낸다.
#include <stdio.h> int main(void) { printf("7 / 3 = %d\n", 7 / 3); printf("7 %% 3 = %d\n", 7 % 3); printf("7 / -3 = %d\n", 7 / -3); printf("7 %% -3 = %d\n", 7 % -3); printf("-7 / 3 = %d\n", -7 / 3); printf("-7 %% 3 = %d\n", -7 % 3); printf("-7 / -3 = %d\n", -7 / -3); printf("-7 %% -3 = %d\n", -7 % -3); return 0; }
7 / 3 = 2 7 % 3 = 1 7 / -3 = -2 7 % -3 = 1 -7 / 3 = -2 -7 % 3 = -1 -7 / -3 = 2 -7 % -3 = -1피제수가 양수일 때 7 / 3 또는 7 / -3은 나머지가 1이 된다. 그러나 -7 / 3 또는 -7 / -3의 나머지는 -1이 된다. 그리고 나눗셈의 결과는 몫을 나타내게 된다.
따라서 나눗셈을 하게 되면 소수의 정수부를 얻는 것과 같은 결과를 얻게 된다.
그렇다면 C++에서는 어떻게 되는지 살펴보자. 코드부터 살펴보면 아래와 같다.
#include <iostream> using namespace std; int main(void) { cout<<"7 / 3 = "<<7 / 3<<endl <<"7 % 3 = "<<7 % 3<<endl <<"7 / -3 = "<<7 / -3<<endl <<"7 % -3 = "<<7 % -3<<endl <<"-7 / 3 = "<<-7 / 3<<endl <<"-7 % 3 = "<<-7 % 3<<endl <<"-7 / -3 = "<<-7 / -3<<endl <<"-7 % -3 = "<<-7 % -3<<endl; return 0; }
7 / 3 = 2 7 % 3 = 1 7 / -3 = -2 7 % -3 = 1 -7 / 3 = -2 -7 % 3 = -1 -7 / -3 = 2 -7 % -3 = -1즉, C++ 역시 C언어와 같다는 것을 알 수 있다.
그럼 이번에는 파이썬을 살펴보자.
파이썬의 경우에는 나머지의 부호는 제수의 부호와 같게 된다. 또한, 나눗셈의 결과는 몫을 나타낸다.(파이썬 2의 경우에는 나눗셈만 해도 그 결과는 몫이고, 3의 경우에는 몫 연산자를 사용할 경우 몫이 나온다.)
print('7 // 3 = ', 7 // 3) print('7 % 3 = ', 7 % 3) print('7 // -3 = ', 7 // -3) print('7 % -3 = ', 7 % -3) print('-7 // 3 = ', -7 // 3) print('-7 % 3 = ', -7 % 3) print('-7 // -3 = ', -7 // -3) print('-7 % -3 = ', -7 % -3) print('7.2 // 3 = ', 7.2 // 3) print('7.2 % 3 = ', 7.2 % 3) print('7.2 // -3 = ', 7.2 // -3) print('7.2 % -3 = ', 7.2 % -3) print('-7.2 // 3 = ', -7.2 // 3) print('-7.2 % 3 = ', -7.2 % 3) print('-7.2 // -3 = ', -7.2 // -3) print('-7.2 % -3 = ', -7.2 % -3)
7 // 3 = 2 7 % 3 = 1 7 // -3 = -3 7 % -3 = -2 -7 // 3 = -3 -7 % 3 = 2 -7 // -3 = 2 -7 % -3 = -1 7.2 // 3 = 2.0 7.2 % 3 = 1.2 7.2 // -3 = -3.0 7.2 % -3 = -1.8 -7.2 // 3 = -3.0 -7.2 % 3 = 1.8 -7.2 // -3 = 2.0 -7.2 % -3 = -1.2이번에는 제수가 양수일 때 나머지의 부호가 양수가 되고, 음수일 때는 부호가 음수가 된다.
따라서 C언어와 비교했을 때 몫이 다르게 나옴을 알 수 있다. 즉, C언어와는 달리 소수의 정수부를 얻지 못한다. 이럴 경우에는 int 함수를 통해서 정수부를 구할 수 있다.
그런데, 파이썬에서는 C나 C++과 달리 소수에 대해서도 몫 연산과 나머지 연산이 가능하다. 자바에서도 마찬가지로 가능한데, 소수이더라도 정수와 같은 규칙이 적용되어 몫과 나머지가 구해진 것을 알 수 있다.
마지막으로 자바를 보자.
public class Divide { public static void main(String[] args) { System.out.println("7 / 3 = " + 7 / 3); System.out.println("7 % 3 = " + 7 % 3); System.out.println("7 / -3 = " + 7 / -3); System.out.println("7 % -3 = " + 7 % -3); System.out.println("-7 / 3 = " + -7 / 3); System.out.println("-7 % 3 = " + -7 % 3); System.out.println("-7 / -3 = " + -7 / -3); System.out.println("-7 % -3 = " + -7 % -3); System.out.println("7.2 / 3 = " + (int)(7.2 / 3)); System.out.println("7.2 % 3 = " + 7.2 % 3); System.out.println("7.2 / -3 = " + (int)(7.2 / -3)); System.out.println("7.2 % -3 = " + 7.2 % -3); System.out.println("-7.2 / 3 = " + (int)(-7.2 / 3)); System.out.println("-7.2 % 3 = " + -7.2 % 3); System.out.println("-7.2 / -3 = " + (int)(-7.2 / -3)); System.out.println("-7.2 % -3 = " + -7.2 % -3); } }
7 / 3 = 2 7 % 3 = 1 7 / -3 = -2 7 % -3 = 1 -7 / 3 = -2 -7 % 3 = -1 -7 / -3 = 2 -7 % -3 = -1 7.2 / 3 = 2 7.2 % 3 = 1.2000000000000002 7.2 / -3 = -2 7.2 % -3 = 1.2000000000000002 -7.2 / 3 = -2 -7.2 % 3 = -1.2000000000000002 -7.2 / -3 = 2 -7.2 % -3 = -1.2000000000000002자바의 경우에는 C나 C++과 같은 결과를 보여준다는 것을 알 수 있다. 즉, 나머지의 부호는 피제수의 부호와 같다. 그리고 나눗셈의 경우 당연히 몫을 나타내고 있다.
그리고 파이썬과 마찬가지로 소수에 대한 나머지 계산이 가능한데, 이 경우에도 위와 같은 규칙으로 나머지가 구해지고 int로 캐스팅 했을 때 위와 같은 몫이 나온다는 것을 알 수 있다.
이런 점에서 나눗셈을 통해서 몫이나 나머지를 구하거나 연산할 때 주의해야 할 필요가 있다
참고 문헌:
http://en.wikipedia.org/wiki/Remainder
댓글 없음:
댓글 쓰기