2013-08-28 15 views
1

Big Integer 클래스 (교훈적인 목적)를 개발 중이며 Ruby를 사용하여 테스트 케이스를 생성했습니다. 내 클래스는 다음의 시험에 실패루비와 파이썬의 긴 구분이 GMP와 Java BigInteger와 다른 이유는 무엇입니까?

a = -48197174570431531987668852939807674377435188974148779416366905274642031729688518691 
b = 4322669160730708444058642850762359547515258361061655693150034467061 
a/b = -11149864303351921 # Ruby answer 

나는 내가 다른 툴과 놀라움과 결과를 확인하려고 내 코드에서 버그를 찾을 수 없습니다 : 오.

는 GMP, 자바의 BigInteger와 내 수업이 결과와 일치한다 :

11149864303351920 
-11149864303351920 

그러나 루비와 파이썬이 일치 :

-11149864303351921 
11149864303351920 

누군가는 설명 할 수 왜 이런 행동을?하시기 바랍니다.

+3

나는 부정적인 결과가 파이썬과 루비 한 적은 이유를 요구하고있다 생각합니다. 파이썬에서 정수 나누기 플로어 [here is why] (http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html). –

+0

@StevenRumbalski, 네, 그게 제가 찾고 있던 것입니다. – rendon

답변

1

정수 나누기에 대한 인수가 모두 양수가 아닌 경우 나머지의 부호 및 부호를 반올림하기위한 결정을 내려야합니다. GMP는 바닥 분할 (f_div ...), ceiling division (c_div ...) 및 truncating division (t_div ...)을 지원합니다.

파이썬을 통해 GMP에 액세스 할 수 gmpy2를 사용

,

>>> import gmpy2 
>>> a = -48197174570431531987668852939807674377435188974148779416366905274642031729688518691 
>>> b = 4322669160730708444058642850762359547515258361061655693150034467061 
>>> gmpy2.f_divmod(a,b) 
(mpz(-11149864303351921), mpz(1542354793066875276328139562907995977816446564586050094773477055490)) 
>>> gmpy2.c_divmod(a,b) 
(mpz(-11149864303351920), mpz(-2780314367663833167730503287854363569698811796475605598376557411571)) 
>>> gmpy2.t_divmod(a,b) 
(mpz(-11149864303351920), mpz(-2780314367663833167730503287854363569698811796475605598376557411571)) 
>>> help(gmpy2.f_divmod) 
f_divmod(x, y) -> (quotient, remainder) 

Return the quotient and remainder of x divided by y. The quotient 
is rounded towards -Inf (floor rounding) and the remainder will 
have the same sign as y. x and y must be integers. 

>>> help(gmpy2.c_divmod) 
c_divmod(x, y) -> (quotient, remainder) 

Return the quotient and remainder of x divided by y. The quotient 
is rounded towards +Inf (ceiling rounding) and the remainder will 
have the opposite sign of y. x and y must be integers. 

>>> help(gmpy2.t_divmod) 
t_divmod(x, y) -> (quotient, remainder) 

Return the quotient and remainder of x divided by y. The quotient 
is rounded towards zero (truncation) and the remainder will have 
the same sign as x. x and y must be integers. 
1

문제는 정수로 나뉩니다. 파이썬 2.x (그리고, 나는 루비이지만, 전문가는 아니지만) 기본적으로 정수 나누기를한다. 당신이 파이썬에서이 작업을 수행하는 경우 :

from __future__ import division 

a = -48197174570431531987668852939807674377435188974148779416366905274642031729688518691 
b = 4322669160730708444058642850762359547515258361061655693150034467061 

print int(a/b) 

을 당신은 당신이 기대하고있는 답변을 볼 수 있습니다.

이 동작은 파이썬 3+에서 기본이며, from __future__ 가져 오기는 파이썬 2.2+에서만 사용할 수 있습니다.

여기에 더 많은 정보가 있습니다. 정수 부문 Wikipedia의 호의 :)에

편집 : 스티브 Rumbalski가 지적 하듯이

, 중요한 차이는 반올림이 일어나는 방법이다. 파이썬의 정수 나누기는 0으로가 아닌 음의 무한대로 반올림됩니다 (-0.2가 -1이됩니다). 부동 소수점 ("true") 나눗셈을 강제하고 마지막으로 int으로 캐스팅하면 위에서 반올림이 다르게 수행된다는 것을 의미하므로 위 예제가 "올바른"답변을 얻는 이유입니다.

+1

-1. 부동 소수점 응답을 찾는 것처럼 보이지 않습니다. 그것이 사실이라면 당신의 대답은 틀립니다. –

+0

@StevenRumbalski - 나는 OP가 GMP, Java 및 그 자신의 클래스 사이의 불일치에 대한 설명을 찾고 있다고 생각하고, Python과 Ruby 테스트는 다른 것에 대해 설명합니다. 정답은 제가 지적한대로입니다 : 파이썬과 루비 예제는 정수 나누기를 사용하고 있습니다. 그게 옳지 않아? – simon

+1

그가 준 결과를보십시오. 정수 결과는 괜찮습니다. java의 BigInteger를 보면 분할 결과가 또 다른 BigInteger입니다. –