C와 Python-모듈로 (%) 연산의 다른 동작
동일한 모드 작업이 사용되는 언어에 따라 다른 결과를 생성한다는 것을 발견했습니다.
Python에서 :
-1 % 10
9를 생성
C에서는 -1 을 생성합니다 !
- 어느 것이 올바른 모듈로입니까?
- C에서 mod 작업을 Python과 동일하게 만드는 방법은 무엇입니까?
- 두 변형 모두 정확하지만 수학 (특히 숫자 이론)에서는 Python의 모듈로 가 가장 일반적으로 사용됩니다.
- C에서는
((n % M) + M) % M
Python과 동일한 결과를 얻습니다. 예.((-1 % 10) + 10) % 10
. 양의 정수 :((17 % 10) + 10) % 10 == 17 % 10
및 C 구현의 두 변형 (양수 또는 음수 나머지)에 대해 여전히 작동하는 방식에 유의하십시오 .
파이썬에는 "진정한"모듈로 연산이 있고 C에는 나머지 연산이 있습니다.
음의 정수 나누기가 처리되는 방식, 즉 0 또는 마이너스 무한으로 반올림되는 방식과 직접적인 관계가 있습니다. 파이썬은 마이너스 무한으로 반올림하고 C (99)는 0으로 반올림하지만 두 언어 모두 (n/m)*m + n%m == n
에서이므로 % 연산자는 올바른 방향으로 보상해야합니다.
Ada는 더 명시 적이며 as mod
및 rem
.
C89 / 90에서 나눗셈 연산자와 음수 피연산자가있는 나머지 연산자의 동작은 구현 에 따라 정의됩니다 . 즉, 구현에 따라 두 동작 중 하나를 얻을 수 있습니다. 운영자가 서로 동의하면됩니다 : from a / b = q
및 a % b = r
follows a = b * q + r
. 결과에 비판적으로 의존하는 경우 코드에서 정적 어설 션을 사용하여 동작을 확인합니다.
C99에서는 관찰하는 동작이 표준이되었습니다.
사실, 두 행동 모두 특정 논리를 가지고 있습니다. Python의 동작은 진정한 모듈로 연산을 구현합니다. 관찰 한 동작은 C가 0으로 반올림하는 것과 일치합니다 (Fortran 동작이기도합니다).
0쪽으로 반올림 C 바람직하다 이유 중 하나는 결과 기대하는 것은 오히려 자연스러운 것입니다 -a / b
같은 수를 -(a / b)
. 실제 모듈로 동작의 경우 -1 % 10
9로 평가되며 이는 -1 / 10
-1이어야 함을 의미합니다 . 이것은 -(1 / 10)
0 이기 때문에 다소 부 자연스럽게 보일 수 있습니다 .
는와 -1 modulo 10
동일 하므로 두 답변 모두 정확합니다 9 modulo 10
.
r = (a mod m)
a = n*q + r
당신은 확신 할 수 |r| < |n|
있지만의 가치가 무엇인지는 알 수 없습니다 r
. 부정적인 대답과 긍정적 인 두 가지 대답이 있습니다.
C89에서는 대답이 항상 정확하지만 모듈로 연산의 정확한 값 (나머지라고 함)은 정의되지 않았으므로 음의 결과 또는 양의 결과가 될 수 있습니다. C99에서는 결과가 정의됩니다.
그래도 긍정적 인 대답을 원하면 대답이 부정적이라면 간단히 10을 더할 수 있습니다.
모듈로 연산자가 모든 언어에서 동일하게 작동하도록하려면 다음 사항을 기억하십시오.
n mod M == (n + M) mod M
그리고 일반적으로 :
n mod M == (n + X * M) mod M
유클리드 나눗셈을 수행 a = b*q + r
하는 것은 분수 a/b
를 정수 몫으로 반올림 q
한 다음 나머지를 계산하는 것과 같습니다 r
.
표시되는 결과는 몫을 반올림하는 데 사용되는 규칙에 따라 다릅니다.
0쪽으로 반올림하면 (잘라 내기) C에서와 같이 0 주위의 대칭을 얻게됩니다.
truncate(7/3) = 2
7 = 3*2 + 1
truncate(-7/3) = -2
-7 = 3* -2 - 1
truncate(7/-3) = -2
7 = -3* -2 + 1
음의 무한대 (바닥)쪽으로 반올림하면 Python에서와 같이 나머지가 표시됩니다.
floor(7/3) = 2
7 = 3*2 + 1
floor(-7/3) = -3
-7 = 3* -3 + 2
floor(7/-3) = -3
7 = -3* -3 - 2
가장 가까운 int로 반올림하면 (원하는대로, 짝수 또는 0에서 멀어짐) 중앙 모듈로가됩니다.
round(7/3) = 2
7 = 3*2 + 1
round(8/3) = 3
8 = 3*3 - 1
round(-7/3) = -2
-7 = 3* -2 - 1
round(7/-3) = -2
7 = -3* -2 + 1
You could try to implement your own modulo with rounding toward positive infinity (ceil), and you would invent a rather unconventional modulo, but it would still be kind of modulo...
Since python 3.7 you can also use .remainder()
from math
built-in module.
Python 3.7.0a0 (heads/master:f34c685020, May 8 2017, 15:35:30)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> math.remainder(-1, 10)
-1.0
From docs:
Return the IEEE 754-style remainder of x with respect to y. For finite x and finite nonzero y, this is the difference
x - n*y
, where n is the closest integer to the exact value of the quotientx / y
. Ifx / y
is exactly halfway between two consecutive integers, the nearest even integer is used forn
. The remainderr = remainder(x, y)
thus always satisfiesabs(r) <= 0.5 * abs(y)
.Special cases follow IEEE 754: in particular,
remainder(x, math.inf)
is x for any finite x, andremainder(x, 0)
andremainder(math.inf, x)
raise ValueError for any non-NaN x. If the result of the remainder operation is zero, that zero will have the same sign as x.On platforms using IEEE 754 binary floating-point, the result of this operation is always exactly representable: no rounding error is introduced.
참고URL : https://stackoverflow.com/questions/1907565/c-and-python-different-behaviour-of-the-modulo-operation
'code' 카테고리의 다른 글
두 숫자의 해시 코드 만들기 (0) | 2020.11.24 |
---|---|
하노이 타워 : 재귀 알고리즘 (0) | 2020.11.24 |
내부 블록 수준 요소 중첩 (0) | 2020.11.24 |
다른보기 내에서보기를 호출 할 수 있습니까? (0) | 2020.11.24 |
Windows 배치 파일 : 그렇지 않은 경우 (0) | 2020.11.24 |