Python的multiply()和prod()结果错误

发布于 2024-08-22 00:47:43 字数 447 浏览 3 评论 0原文

任何人都可以解释以下内容吗?我正在使用 Python 2.5

考虑 1*3*5*7*9*11 ... *49。如果您在 IPython(x,y) 交互式控制台中输入所有内容,您将得到 58435841445947272053455474390625L,这是正确的。 (为什么是奇数:就像我最初做的那样)

Python multiply.reduce() 或 prod() 应该在等效范围内产生相同的结果。在某种程度上,确实如此。在这里,它已经是错误的:

: k = range(1, 50, 2)
: multiply.reduce(k)
: -108792223

使用 prod(k) 也会生成 -108792223 作为结果。对于长度为 12 的等效范围(即 k = range(1,24,2)),其他不正确的结果开始出现。

我不知道为什么。有人可以帮忙吗?

Can anyone explain the following? I'm using Python 2.5

Consider 1*3*5*7*9*11 ... *49. If you type all that from within IPython(x,y) interactive console, you'll get 58435841445947272053455474390625L, which is correct. (why odd numbers: just the way I did it originally)

Python multiply.reduce() or prod() should yield the same result for the equivalent range. And it does, up to a certain point. Here, it is already wrong:

: k = range(1, 50, 2)
: multiply.reduce(k)
: -108792223

Using prod(k) will also generate -108792223 as the result. Other incorrect results start to appear for equivalent ranges of length 12 (that is, k = range(1,24,2)).

I'm not sure why. Can anyone help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

走过海棠暮 2024-08-29 00:47:43

这是因为numpy.multiply.reduce()将范围列表转换为numpy.int32类型的数组,并且reduce操作溢出了可以存储在32位中的内容某些点:

>>> type(numpy.multiply.reduce(range(1, 50, 2)))
<type 'numpy.int32'>

正如 Mike Graham 所说,您可以使用 dtype 参数来使用 Python 整数而不是默认值:

>>> res = numpy.multiply.reduce(range(1, 50, 2), dtype=object)
>>> res
58435841445947272053455474390625L
>>> type(res)
<type 'long'>

但是在这种情况下使用 numpy 处理 python 对象是没有意义的,最好的解决方案是 KennyTM 的:

>>> import functools, operator
>>> functools.reduce(operator.mul, range(1, 50, 2))
58435841445947272053455474390625L

This is because numpy.multiply.reduce() converts the range list to an array of type numpy.int32, and the reduce operation overflows what can be stored in 32 bits at some point:

>>> type(numpy.multiply.reduce(range(1, 50, 2)))
<type 'numpy.int32'>

As Mike Graham says, you can use the dtype parameter to use Python integers instead of the default:

>>> res = numpy.multiply.reduce(range(1, 50, 2), dtype=object)
>>> res
58435841445947272053455474390625L
>>> type(res)
<type 'long'>

But using numpy to work with python objects is pointless in this case, the best solution is KennyTM's:

>>> import functools, operator
>>> functools.reduce(operator.mul, range(1, 50, 2))
58435841445947272053455474390625L
毁虫ゝ 2024-08-29 00:47:43

CPU 不会将任意大的数字相乘,它只执行对以 2 基数、0-1 位表示的特定数字范围定义的特定运算。

Python '*' 通过正确的表示和 CPU 或 FPU 乘法指令之外的特殊代码完美地处理大整数。

对于语言来说,这实际上是不寻常的。

在大多数其他语言中,数字通常表示为固定的位数组。例如,在 C 或 SQL 中,您可以选择使用 8 位整数来表示 0 到 255,或 -128 到 +127,或者您可以选择使用 16 位整数来表示最多 2^16-1,即65535. 当只能表示一定范围的数字时,使用 * 或 + 等操作超出限制可能会产生不良效果,例如得到负数。您可能在使用外部库时遇到过这样的问题,该库可能是原生 C 而不是 python。

The CPU doesn't multiply arbitrarily large numbers, it only performs specific operations defined on particular ranges of numbers represented in base 2, 0-1 bits.

Python '*' handles large integers perfectly through a proper representation and special code beyond the CPU or FPU instructions for multiply.

This is actually unusual as languages go.

In most other languages, usually a number is represented as a fixed array of bits. For example in C or SQL you could choose to have an 8 bit integer that can represent 0 to 255, or -128 to +127 or you could choose to have a 16 bit integer that can represent up to 2^16-1 which is 65535. When there is only a range of numbers that can be represented, going past the limit with some operation like * or + can have an undesirable effect, like getting a negative number. You may have encountered such a problem when using the external library which is probably natively C and not python.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文