【问题标题】:Python - Precision Loss With Large IntegerPython - 大整数的精度损失
【发布时间】:2014-07-12 02:10:16
【问题描述】:

编辑

工作!!!谢谢各位的意见! //= 函数中需要从 2.x 移植到 3.x

我正在尝试及时在 Python 中分解非常大的数字。这是可行的,除非素数的值与原始值相乘时存在很大差异。

代码:

import math

x = 4327198439888438284329493298321832193892183218382918932183128863216694329


def getPrimes(n):
    num = abs(n)
    factor = 2
    primes = []
    while num > 1:
        factor = getNext(num, factor)
        primes.append(factor)
        num /= factor
    if n < -1:
        primes[0] = -primes[0]
    return primes

def getNext(n, f):
    if n % 2 == 0:
        return 2
    for x in range(max(f, 3), int(math.sqrt(n) + 1), 2):
        if n % x == 0:
            return x
    return n

values = getPrimes(x)

orig = int(1);

print(values)
for y in values:
    orig *= int(y)

print("\n") 
print(x)
print("\n")
print(orig)
print("\n")
print(orig-x)

输出:

[17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 83, 20845357395553.0]


4327198439888438284329493298321832193892183218382918932183128863216694329


4327198439888438374354383059307859040070974971297410068584490149575917568


90024889760986026846178791752914491136401361286359223239

???

当将原始数字除以时,它能够很好地达到质因数之一。这让我确信我在上述因式分解中得到的因素是正确的。

>>> x /= 17
>>> x /= 20845357395553
>>> x /= (2**185)
>>> x /= 3
>>> x
83.0
>>> x /= 83
>>> x
1.0
>>>

TL;DR

我认为 python 的代码在大数 (int) 乘法中存在错误,或者我正在做一些绝对疯狂的事情,健全性检查!

谢谢!

编辑

我在在线 python 解释器中编写了第二个示例代码,特别是 2.xx 而不是 3.xx,但正如你们中的一些人所说,我确实在 3.x 中运行了代码。重做了3.xx中的第二个操作并替换。不知道是否有人知道为什么代码有两个不同的值应该相同。

编辑 - 2014 年 7 月 12 日

经过进一步检查,似乎我有一个因素不正确的情况(使用 Wolfram Alpha 检查)并且我已经切换了算法。稍后我将在 2.7 中使用 long 进行测试。

【问题讨论】:

  • 使用其他类型,int 保存范围数量。搜索其他数字类型,例如 longfloatdecimal
  • @Niang:对int的操作如果结果太大会自动切换到long
  • 您使用的是 Python 2 还是 Python 3?如果你使用的是 Python 3,你会得到浮点除法(这会失去精度),但如果你使用的是 Python 3,你不应该在 82L 中看到 L。那么也许您在 3 中运行代码,但在 2 中运行测试?
  • 我相信您正在混淆您的 Python 版本。您遇到的问题与使用浮点除法而不是整数除法一致,并且您的 range 没有崩溃这一事实表明 Python 3,但 L 后缀表明 Python 2。使用 // 表示整数除法,无论是在 Python 2 还是 3 上。
  • 顺便说一句,您可能想选择更小的东西进行测试。使用试除法分解这个数字将花费您 很长时间 的时间。第二大素因子是18667156147541389,因此在找到该因子之前,您需要查看算法内部循环的~10^16 次迭代。以每秒百万次的乐观迭代速度,几百年应该可以做到。 :-)

标签: python int multiplication


【解决方案1】:

Python3 has changed what the division operator does.

在 Python 2 中:

>>> 3 / 2
1

在 Python 3 中:

>>> 3 / 2
1.5
>>> 3 // 2
1

因此,您的getprimes() 函数应包含以下代码:

while num > 1:
    factor = getNext(num, factor)
    primes.append(factor)
    num //= factor

【讨论】:

  • 谢谢,这大大增加了程序的运行时间,但我假设那是因为算法实际上正在工作。 :P 谢谢!
猜你喜欢
  • 2015-06-28
  • 1970-01-01
  • 2020-04-26
  • 1970-01-01
  • 2017-12-21
  • 2023-03-09
  • 1970-01-01
  • 2014-07-13
  • 1970-01-01
相关资源
最近更新 更多