관리 메뉴

이쁜왕자 만쉐~~

음수와 모듈로(%) 연산.. 본문

낙서장

음수와 모듈로(%) 연산..

이쁜왕자 2007.10.17 22:03

modulo

모듈로 ( modulo ) 연산자

C 언어에서 % 는 모듈로 연산이며,, 일반적으로 자연수 나눗셈의 나머지 값을 구하는 목적으로 사용된다.. 문제는 이게 음수에 적용되면 아주 골때린 문제를 야기한다..

int a = 12;
printf ("a = %d , a/10 = %d , a%10 = %d\n", a, a/10, a%10);

위와 같은 코드가 있다고 하자.. 이는 별 문제 없이.. 다음과 같은 결과를 낸다..

a = 12, a/10 = 1, a%10 = 2

만약 a = 12 가 아니라 음수인 -12 이면 어떤 출력을 내는지 추측해 보자..

결과는 다음과 같다..

int a = -12;
printf ("a = %d , a/10 = %d , a%10 = %d\n", a, a/10, a%10);
a = -12 , a/10 = -1 , a%10 = -2

음수에 대해서 모듈로 연산을 하면 그 결과 음수가 나온다.. 이에 대한 이유는 사실 간단하다..

피젯수 = 몫 * 젯수 + 나머지

이라는 아주 당연한 식 때문이다.. 12 = 1 * 10 + 2  이기 때문에 12 / 10 = 1 이고, 12 % 10 = 2 이다.. a= -12 인 경우를 생각하면,, -12 = (-1) * 10 + (-2) 이기 때문에 -12 / 10 = -1 이고, -12 % 10 = -2 가 된다..

문제는 어찌보면 당연한 이것 때문에 여러곳에서 문제가 생긴다.. 예를 들면.. 다음과 같은 것이 있다..

변수 b 는 백분률의 x10 한 값을 저장하는 변수 이다.. 34.5% 는 변수 b 에 345 라는 int 값으로 저장된다.. 이처럼 실제로는 실수 이지만,, n 배한 값을 정수 변수에 저장하는 경우도 있다.. 이 b 를 백분률로 출력해주는 함수는 보통 이렇게 만들어 진다..

int b = 345;
printf ("b = %d.%1d%%\n", b/10, b%10);
b = 34.5%

b 가 0 보다 큰 양수값을 가지는 동안에는 아무런 문제가 없지만,, b 가 음수가 되면 바로 문제가 발생한다.. 만약 b = -345 라고 하면,, 다음과 같이 출력된다..

int b = -345;
printf ("b = %d.%1d%%\n", b/10, b%10);
b = -34.-5%

이를 보정하기 위해서 다음과 같이 바꿀 수 있다..

int b = -345;
printf ("b = %d.%1d%%\n", b/10, (b>=0)? b%10:(-b)%10);
b = -34.5%

일단은 제대로 동작하도록 수정한듯 싶지만,, 여전히 문제가 남아 있다.. b = -5 인 경우는 이렇게 된다..

int b = -5;
printf ("b = %d.%1d%%\n", b/10, (b>=0)? b%10:(-b)%10);
b = 0.5%

정상적이라면 -0.5% 여야 하지만,, -5 / 10 = 0 이기에, 음수 부호가 찍히지 않고,, 그로 인해서 음수가 양수로 바뀌어 찍혀 버린다..  이걸 바꾸는 건 그리 만만치가 않다.. 결국 if 문으로 음수 양수 구분해서 해결해야 한다..

int b = -5;

if (b>=0)
  printf ("b = %d.%1d%%\n", b/10, b%10);
else
  printf ("b = -%d.%1d%%\n", (-b)/10, (-b)%10);
b = -0.5%

이제 거진 문제가 해결된 듯 싶다.. 하지만,, 아직도 넘어야 할 산이 있다.. 출력되는 숫자의 자리수의 위치를 맞추고 싶다.. 양수인 경우는 %5d 등을 이용하면 쉽게 해결된다.. 부호 포함 정수부 5자리, 소수점 이하 1자리를 출력하고프면 다음과 같이 하면 된다.. 양수의 경우는 쉽게 해결되지만,, 음수인 경우는 점점 산으로 가게 된다..

int b = -5;

if (b>=0)
  printf ("b = %5d.%1d%%\n", b/10, b%10);
else
{
  char temp_buf[20];
  sprintf(buf, "-%d.%1d", (-b)/10, (-b)%10);
  printf ("b = %7.7s%%\n", buf);
}


b =    -0.5%

아무래도 왠만하면 double 이나 float 를 쓰는 방향으로 다시 고려해야 아닌가 싶어 진다..
저런 골치아픈 문제가,, 이렇게 간단하게 해결되니 말이다..

int b = -5;
printf ("b = %7.1lf%%\n", (double)b/10.0);

b =    -0.5%

- 이쁜왕자 -
- Valken the SEXy THief~~ ^_* -
신고
1 Comments
  • 프로필사진 지가나던자 2017.09.26 16:02 신고 원래 모듈로 연산에서 정의되는 나머지값은 무조건 양수여야 합니다. C언어 연산에서는 이를 고려하지 않은채로 정의해서 나머지가 음수가 나오는 것입니다. 이는 윈도우 계산기에서도 마찬가지고요. 구글 계산기를 이용해보시면 다른 결과를 얻으실수 있을 겁니다
댓글쓰기 폼