1

我正在开发一个 Big Integer 类(教学目的),我一直在使用 Ruby 来生成测试用例。我的课程在以下测试中失败:

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

我在我的代码中找不到错误,因此我尝试使用其他工具验证结果并感到惊讶:o。

GMP、Java BigInteger 和我的课与这个结果不谋而合:

11149864303351920
-11149864303351920

但 Ruby 和 Python 恰逢这一点:

-11149864303351921
11149864303351920

有人可以解释为什么这种行为吗?,请。

4

2 回答 2

1

当整数除法的参数不是两个正数时,必须决定对商和余数的符号进行四舍五入。GMP 支持地板除法 (f_div...)、天花板除法 (c_div...) 和截断除法 (t_div...)。

使用 gmpy2 通过 Python 访问 GMP,

>>> 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.
于 2013-08-28T04:50:50.167 回答
1

问题在于整数除法。python 2.x(我假设是 ruby​​,虽然我不是那里的专家)默认情况下进行整数除法。如果你在 python 中这样做:

from __future__ import division

a = -48197174570431531987668852939807674377435188974148779416366905274642031729688518691
b = 4322669160730708444058642850762359547515258361061655693150034467061

print int(a/b)

你会看到你期待的答案。

请注意,此行为在 python 3+ 中是默认行为,并且from __future__导入仅在 python 2.2+ 中可用。

这里有更多信息。关于整数除法,由维基百科提供:)

编辑:

正如 Steve Rumbalski 所指出的,显着的区别在于舍入的方式。Python 的整数除法向负无穷大舍入,而不是向零舍入(这样 -0.2 变为 -1)。正如我在上面所做的那样,强制浮点(“真”)除法然后int在最后进行转换,这意味着舍入的方式不同,这就是我上面的示例得到“正确”答案的原因。

于 2013-08-28T04:36:51.240 回答