파이썬에서 정수 나누기와 float 대 int 변환의 차이점은 무엇입니까?


52

최근 int()에는 부동 소수점을 0으로 반올림하는 반면 정수 나누기는 플로트를 바닥으로 반올림합니다.

예를 들어 :

-7 // 2 = -4
int(-7/2) = -3

나는 다음을 지정하는 문서를 읽었습니다.

int (x, base = 10) 클래스

숫자 또는 문자열 x로 구성된 정수 객체를 반환하거나 인수가 제공되지 않으면 0을 반환합니다. x가 숫자이면 x를 반환하십시오. int (). 부동 소수점 숫자의 경우이 값은 0을 향해 잘립니다.

과:

층 구분

가장 가까운 정수로 내림하는 수학 나누기 . 바닥 구분 연산자는 //입니다. 예를 들어, 식 11 // 4는 float true division으로 반환 된 2.75와 달리 2로 평가됩니다. (-11) // 4는 -2.75이므로 아래로 반올림되므로 -3입니다. PEP 238을 참조하십시오.

그러나 2 개의 유사한 연산 (float division to integer)이 다른 결과를 반환해야한다는 것은 비논리적 인 것 같습니다.

기능 간의 차이점에 대한 동기가 있습니까?

감사합니다.


답변:


61

일관성.

이해하기 위해서는 매우 기본적이고 겉으로는 관련이없는 설명을 따라야합니다.

학교에서 당신은 나머지 부분을 나누었습니다. 그리고 당신은 다음과 같은 계산을 수행했습니다 :

8 ÷ 4 = 2 R 0
7 ÷ 4 = 1 R 3
6 ÷ 4 = 1 R 2
5 ÷ 4 = 1 R 1
4 ÷ 4 = 1 R 0
3 ÷ 4 = 0 R 3
2 ÷ 4 = 0 R 2
1 ÷ 4 = 0 R 1
0 ÷ 4 = 0 R 0
        ^------ This is the result of x // 4
            ^-- This is the result of x % 4 (modulo)

나중에 실수에 대한 나눗셈을 배웠습니다.

8 ÷ 4 = 2.0
7 ÷ 4 = 1.75
6 ÷ 4 = 1.5
5 ÷ 4 = 1.25
4 ÷ 4 = 1.0
3 ÷ 4 = 0.75
2 ÷ 4 = 0.5
1 ÷ 4 = 0.25
0 ÷ 4 = 0.0
        ^--- Note that the number in front of the . is int(x/4)

이 시점까지, 당신은 믿을 수 x // 4int(x/4)항상 같은 결과를 제공합니다. 그것이 현재 상황에 대한 이해입니다.

그러나 정수 나누기에서 발생하는 일을 살펴보십시오. R 뒤의 숫자는 3, 2, 1에서 0으로 순환 한 다음 다시 시작합니다. 3, 2, 1, 0. R 앞의 숫자는 4 단계마다 감소합니다.

어떻게 진행 될까요?

 8 ÷ 4 =  2 R 0
 7 ÷ 4 =  1 R 3
 6 ÷ 4 =  1 R 2
 5 ÷ 4 =  1 R 1
 4 ÷ 4 =  1 R 0
 3 ÷ 4 =  0 R 3
 2 ÷ 4 =  0 R 2
 1 ÷ 4 =  0 R 1
 0 ÷ 4 =  0 R 0
-1 ÷ 4 = -1 R 3
         ^------ We have to decrease now, because we already have 0 four times
              ^-- We have to restart the cycle at 3

동시에 실수 나누기는 다음을 제공합니다.

-1 ÷ 4 = -0.25
          ^----- There is still a 0 in front of the .

그래서 -1 // 4-1을 int(-1/4)제공 하지만 0을 제공합니다.

기능 간의 차이점에 대한 동기가 있습니까?

글쎄, 그들은 다른 목적을 제공합니다 : //나머지를 가진 정수 계산 int()의 일부이며 .실수 연산 앞에 부분을 제공합니다 .

계산할 대상을 결정한 다음 올바른 결과를 얻기 위해 Python에서 사용할 연산자를 결정합니다.

좋은 질문. 계속 학습하십시오.


11
실제로, 이것은 속임수를 허용합니다 : 만약 당신이 -1 개의 과자를 가지고 4 명의 친구에게 그것을 줄 경우, 3 개의 과자가 남게됩니다. 대단하지 않습니까? -1 과자를 소유하는 방법 만 찾으면됩니다.
Thomas Weller

1
//파이썬 3 에서 연산자를 추가하는 동기 가 int (float)의 사용을 피하기 위해 이해하는 한 일종의 일관성을 만듭니다 . 그렇지 않은 경우 언제 구현을 사용하도록 선택 int()하고 언제 구현해야합니까//
IsaacDj

1
좋아, 그것은 단지 잘못된 가정입니다. 정확성에 대한 가정을 테스트하는 한, 50 %의 경우에는 실패합니다 (적어도 저에게는 그렇지 않습니다). 답변에 그것에 대한 몇 가지 단어를 추가했습니다.
Thomas Weller

2
@IsaacDj "floor division"연산자의 비하인드 스토리 를 읽고 싶을 수도 있습니다 .
bruno desthuilliers

1
@EricLippert : 나는 그것이 기괴하다고 생각하지 않습니다. 손실 된 작업은 정확한 작업과 동일한 결과를 제공한다고 가정 할 수 없습니다. 코드 음성 : Math.Floor(3.23) != -Math.Floor(-3.23)같은 이유로 -((-x)//y)같을 필요는 없습니다 x//y.
Thomas Weller

4

양수에서는 동일하게 작동하기 때문에이 두 작업이 직관적으로 유사해야한다는 관찰이 예상됩니다. 그러나 당신이 그들의 기원 (하나는 수학에서 온 것이고 다른 하나는 컴퓨터 과학에서 온 것)을 보면, 그들의 다른 행동이 더 합리적입니다.

다음과 같은 개념을 살펴볼 수 있습니다.

  • 바닥 나누기 일명 수학 나누기에 적용된 바닥 기능
  • 타입 변환 / 타입 캐스팅

===================================================== ================

I) 플로어 디비전 (일명 수학 디비전에 적용되는 플로어 기능)

바닥 함수는 수학에서 매우 잘 알려진 개념입니다.

에서 mathworld.wolfram :

가장 큰 정수 함수 또는 정수 값이라고도하는 바닥 함수 | _ x_ | (Spanier and Oldham 1987)는 x보다 작거나 같은 가장 큰 정수를 제공합니다. 바닥 기능의 이름과 기호는 KE Iverson (Graham et al. 1994)에 의해 만들어졌습니다.

따라서 바닥 나누기는 수학 나누기에 적용된 바닥 함수에 지나지 않습니다. 동작은 "수학적으로 정확한"매우 명확합니다.

II) 타입 변환 / 타입 캐스팅

에서 위키 피 디아 :

컴퓨터 과학에서 형식 변환, 형식 캐스팅, 형식 강제 및 형식 저글링은 식을 한 데이터 형식에서 다른 데이터 형식으로 변경하는 다른 방법입니다.

대부분의 프로그래밍 언어에서 정수에 대한 부동 소수점 캐스팅은 반올림 규칙에 의해 적용되므로 규칙이 있습니다.

  • 0을 향한 반올림 – 0을 향한 반올림 (잘림이라고도 함)

IEEE 754 에 따른 반올림 규칙 .


다시 말해, 파이썬에서 정수 나누기와 float에서 int 로의 변환이 다른 이유는 수학적인 것입니다. 여기 Guido van Rossum의 생각이 있습니다. 파이썬, 문서의 역사 블로그 "왜 파이썬의 정수 부문 마루" )

이것은 일부 사람들을 방해하지만 좋은 수학적 이유가 있습니다. 정수 나누기 연산 (//)과 그 형제, 모듈로 연산 (%)은 함께 돌아가서 훌륭한 수학적 관계를 만족시킵니다 (모든 변수는 정수임).

나머지 r을 가진 a / b = q

그런

b * q + r = a 및 0 <= r <b

(a와 b가> = 0이라고 가정).

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