파이썬에서 음수에 대한 모듈로 연산


94

음수와 관련하여 Python에서 이상한 동작을 발견했습니다.

>>> -5 % 4
3

아무도 무슨 일이 일어나고 있는지 설명 할 수 있습니까?


25
나에게 맞아 보인다
wheaties

6
..., -9, -5, -1, 3, 7, ...
NullUserException 2010 년


8
를 사용 math.fmod하여 C 또는 Java에서와 동일한 동작을 얻을 수 있습니다 .
0x2b3bfa0

답변:


137

C 또는 C ++와 달리 Python의 모듈로 연산자 ( %)는 항상 분모 (제수)와 동일한 부호를 갖는 숫자를 반환합니다. 당신의 표현은 3을 산출합니다.

(-5) / 4 = -1.25-> floor (-1.25) = -2

(-5) % 4 = (-2 × 4 + 3) % 4 = 3.

음이 아닌 결과가 종종 더 유용하기 때문에 C 동작보다 선택됩니다. 예는 요일을 계산하는 것입니다. 오늘이 화요일 (2 일) 인 경우 N 일 전의 요일은 무엇 입니까? 파이썬에서는 다음과 같이 계산할 수 있습니다.

return (2 - N) % 7

그러나 C에서 N ≥ 3이면 잘못된 숫자 인 음수를 얻고 7을 더하여 수동으로 수정해야합니다.

int result = (2 - N) % 7;
return result < 0 ? result + 7 : result;

( 다른 언어에 대해 결과 기호가 결정되는 방법 은 http://en.wikipedia.org/wiki/Modulo_operator 를 참조하십시오 .)


6
놀랍게도 Python의 모듈로 연산자 (%) 항상 분모 (제수)와 같은 부호를 갖는 숫자를 반환 하지는 않습니다 . stackoverflow.com/questions/48347515/…
zezollo

33

다음은 Guido van Rossum의 설명입니다.

http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html

본질적으로 a / b = q와 나머지 r은 b * q + r = a 및 0 <= r <b의 관계를 유지합니다.


4
C ++ 및 Java와 같은 언어도 첫 번째 관계를 유지하지만 a, 부정적 , 긍정적 b인 반면 Python은 바닥에 있습니다. 그것은 항상 사실이며 abs(r) < b, 그들은 iff를 나타 r <= 0냅니다.
Evgeni Sergeev 2014

9

음수로 정수 나누기와 모드를 처리하는 가장 좋은 방법은 없습니다. a/b같은 크기이고 반대 부호 이면 좋을 것 입니다 (-a)/b. a % b실제로 모듈로 b 라면 좋을 것 입니다. 우리가 정말로 원하기 때문에 a == (a/b)*b + a%b처음 두 개는 호환되지 않습니다.

어느 쪽을 지킬 것인지는 어려운 질문이며 양측 모두에 대한 논쟁이 있습니다. C와 C ++는 정수 나눗셈을 0 (so a/b == -((-a)/b)) 으로 반올림 하며 Python은 그렇지 않습니다.


1
"a / b가 (-a) / b와 같은 크기이고 반대 부호이면 좋을 것입니다." 그게 왜 좋을까요? 이것이 바람직한 행동은 언제입니까?
user76284 2010 년

그런 다음 정규 나눗셈 및 곱셈과 동일한 방식으로 작동하므로 직관적으로 작업하기 쉽습니다. 하지만 수학적으로 말이되지 않을 수도 있습니다.
Demis

6

지적했듯이 Python 모듈로는 다른 언어의 규칙에 대한 합당한 예외를 만듭니다 .

이는 특히 모듈로가 자주 사용되는 //것처럼 정수 나누기 연산자 와 함께 사용할 때 음수에 원활한 동작을 제공합니다 %(math. divmod 에서와 같이 ).

for n in range(-8,8):
    print n, n//4, n%4

생성 :

 -8 -2 0
 -7 -2 1
 -6 -2 2
 -5 -2 3

 -4 -1 0
 -3 -1 1
 -2 -1 2
 -1 -1 3

  0  0 0
  1  0 1
  2  0 2
  3  0 3

  4  1 0
  5  1 1
  6  1 2
  7  1 3
  • 파이썬은 %항상 0 또는 양수를 출력합니다 *
  • 파이썬은 //항상 음의 무한대로 반올림합니다.

* ... 오른쪽 피연산자가 양수이면됩니다. 반면에11 % -10 == -9


덕분에 당신의 예 : 내가 그것을 이해했다
라 미스

5

에서 파이썬 , 나머지 연산자는 다음과 같이 작동합니다.

>>> mod = n - math.floor(n/base) * base

결과는 (귀하의 경우) :

mod = -5 - floor(-1.25) * 4
mod = -5 - (-2*4)
mod = 3

C, JAVA, JavaScript 와 같은 다른 언어 는 바닥 대신 잘림을 사용합니다.

>>> mod = n - int(n/base) * base

결과 :

mod = -5 - int(-1.25) * 4
mod = -5 - (-1*4)
mod = -1

파이썬에서 반올림에 대한 더 많은 정보가 필요하면 이것을 읽으십시오 .



1

나는 또한 그것이 파이썬의 이상한 행동이라고 생각했습니다. 내가 부서를 잘 해결하지 못한 것이 밝혀졌습니다. 나는 몫에 0의 값을, 나머지에 -5의 값을주고 있었다. 끔찍합니다. 정수의 기하학적 표현을 잊어 버렸습니다. 수직선에 의해 주어진 정수의 기하학을 회상함으로써 몫과 나머지에 대한 정확한 값을 얻을 수 있고 파이썬의 동작이 정상인지 확인할 수 있습니다. (이미 오래 전에 우려 사항을 해결했다고 가정하지만).


1

또한 파이썬의 분할이 C와 다르다는 점도 언급 할 가치가 있습니다.

>>> x = -10
>>> y = 37

C에서는 결과를 기대합니다.

0

파이썬에서 x / y는 무엇입니까?

>>> print x/y
-1

%는 나머지가 아닙니다! C에서 x % y는

-10

파이썬이 산출합니다.

>>> print x%y
27

C에서와 같이 둘 다 얻을 수 있습니다.

부문 :

>>> from math import trunc
>>> d = trunc(float(x)/y)
>>> print d
0

그리고 나머지 (위에서 나눈 사용) :

>>> r = x - d*y
>>> print r
-10

이 계산은 가장 빠르지는 않지만 x와 y의 부호 조합에 대해 작동하여 C에서와 동일한 결과를 얻고 조건문을 피합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.