2013-07-04 1 views
19

, 나는 q는 몫이며, r는 (나머지는 음수가 될 수 없다는 지적) 나머지이며, n % d = r가와 d는 제수입니다 n = d*q + r으로 그것에 대해 생각하는 것을 배웠습니다. C에서 모듈러 산술을위한 규칙은 무엇입니까? 이전 클래스에서

그래서 예를 들어, -111 mod 1110 때문에 -111 = -11*-11 + 10 (즉, 우리에게 부정적인 나머지를 줄 것이다 방법으로보고, -111 = -11*10 -1 반대).

그러나 -111 % 11의 결과를 인쇄 할 경우 -1이 아니며 10이 아닙니다. 왜? 이게 기술적으로 잘못 아닌가?

+1

아, 파이썬은 모든 특별한 경우 (수학적 의미에서) 바로 그것을 점점 기억 :-) 이전 음의 피연산자 계수. – Cameron

+0

C의 '%'연산자를 예상 한 방식으로 작동하는 모듈에 적용하려면 다음과 같이하십시오 :'((a % b) + b) % b' – paddy

+2

wikipedia 페이지에 아주 멋진 테이블이 있습니다. 모듈로 각 언어가 어떻게 모듈로 구현되는지 보여주는 연산 : http://en.wikipedia.org/wiki/Modulo_operation –

답변

6

계수의 경우 -1은 잘못된 대답입니다.

연산자는 나머지 연산자이며 나머지는 10 또는 -1을 허용합니다.

+0

모듈러스와 무슨 뜻인지 정의하십시오.문맥에 따라 다른 정의가있는 것처럼 보입니다. ISTM은 -1이 맞을 것입니다. –

+0

@RudyVelthuis : "모듈러스"는 일반적으로 [모듈러 산술]과 관련이 있습니다 (http://mathworld.wolfram.com/ModularArithmetic.html). 최소한 모듈러 산술 연산이 일반적으로 정의되어 있기 때문에 음수가 아닌 숫자 만 허용됩니다. –

+0

내가 말했듯이, 그것은 문맥에 달려있다. 유클리드 분열을 암시한다면, 나머지는 항상 긍정적입니다. 그러나 다른 맥락에서 이것은 반드시 그런 것은 아닙니다. 특히 이것은 프로그래밍 포럼이기 때문에 "모듈"의 의미는 언어마다 다를 수 있음을 알아야합니다. –

4

% 연산자는 a == b * (a/b) + (a % b)이 참이고 정수 나누기를 사용하도록 구현됩니다.

이 경우 -111/11-10이므로 -111 == 11 * -10 + xx == -1으로 충족됩니다.

+0

IOW,'a % b = a - (a/b) * b'. '-111/11'의 결과는'-10'이므로 결과는'-111 - (-10 * 11)'즉'-1'입니다. –

19

짧은 답변 :

(a/b)*b + a%ba 같다는 것을 표준 보증.

C99에서 나누기 /의 결과는 0으로 잘립니다. % 연산자의 결과는이 경우 -1입니다.

C89에서 division /의 결과는 음수 피연산자에 대해 잘릴 수 있습니다. 따라서 % 연산자의 결과는 기계에 따라 다릅니다.

긴 않음 : C99 6.5.5

5/연산자의 결과로부터

는 번째로 첫 번째 피연산자의 분할로부터의 몫이고; % 연산자의 결과는 나머지 값입니다. 두 연산 모두에서 의 값이 두 번째 피연산자가 0이면 동작은 정의되지 않습니다.

6 정수를 나눌 때/연산자의 결과는 소수 부분이 삭제 된 대수 몫입니다. 몫 a/b가 표현 가능한 경우, 표현 (a/b) * b + a % b는 a와 같아야합니다. 그렇지 않으면 a/b와 a % b의 동작은 정의되지 않은 입니다.

그리고 같은 페이지에 각주는 / 작품, 그것이 말하는 방법을 설명하기 :

이 종종 '0으로 절단' ''라고합니다.

이 규칙에 따르면, -111/11이뿐만 아니라 1 (a/b)*b + a%b 때문에이 a 동일해야합니다, -10 할 수 있습니다, 우리는 -111 % 11-1입니다 있습니다. 조치가 취해진 다 같이

대한 절단의 방향 및/%에 대한 결과의 표시 장치 의존 음의 피연산자 같습니다

그러나 K & R 장 2.5 다른 답을 준다 오버플로 또는 언더 플로.

이 내용에 따르면 -1 또는 10이 합법적 인 결과 일 수 있습니다.

이유는 C89 3.3.5이다 :

정수 분할 두 피연산자가/연산자의 결과 긍정적 인 경우 분할이 부정확 졌을 대수 지수보다 큰 정수 이하 % 연산자의 결과는 양수입니다. 두 피연산자가 음수이면/연산자의 결과가 대수 몫보다 작은 가장 큰 정수 또는 대수 몫보다 큰 가장 작은 정수인지 여부는 구현자가 정의합니다 (% 연산자 결과의 부호와 동일). 몫 a/b가 표현 가능한 경우, 표현 (a/b) * b + a % b는 a와 같아야합니다.

C89에서 C99로 변경되었습니다.

C99 근거 6.5.5 일부 역사적인 이유로 제공 구현 정의 방식으로 상하로 반올림 수 네거티브 피연산자를 포함한 정수 C89에서

, 분할 단계; 의도는 특별한 경우를 확인하고 특정 동작을 시행하기 위해 런타임 코드에서 오버 헤드가 발생하지 않도록하는 것이 었습니다. 그러나 Fortran에서는 결과가 항상 0으로 잘 리며 오버 헤드가 숫자 프로그래밍 커뮤니티에서 받아 들일 수 있습니다. 따라서 C99는 이제 Fortran에서 C 로의 코드 포팅을 용이하게 해주는 유사한 동작을 요구합니다.이 문서의 §7.20.6.2의 표는 필요한 의미를 보여줍니다.

그리고 여기가 §7.20.6.2 테이블의 :

numer denom quot rem 
7  3 2 1 
–7  3 –2 –1 
7  –3 –2 1 
–7  –3 2 –1 
+1

나는 허용 된 각주 90 (C99 표준의 버전 n1256에서)은 "[...] 부분적인 부분이 폐기 된 대수 몫에 대한 텍스트에서"이것은 종종 절단이라고 부릅니다 0 "을 향해. 그래서 저는'-111/11'이 -10 일 뿐이므로 '(a/b) * b + a % b'라는 요구 때문에'-111 % 11'은 -1이 될 수 있습니다. 'a'와 같아야합니다. –

+0

또한 비트 연산자는 다르게 작동합니다! '&'와'>>'는 보통 2의 거듭 제곱의 모듈러스와 나눗셈과 비교되지만, >> >>는 "0으로 잘라 버리지"않기 때문에'-5 >> 1 == -3'과'- 11 & 3 == 1' ('-11 % 4 == -3' 인 동안) –

+1

예, 이것은 C99에서 변경되었습니다. C89 컴파일러는이 중 하나를 수행 할 수 있으며 일반적으로 하드웨어에 가장 편리한 모든 것을 수행합니다. – torek

관련 문제