【问题标题】:Python 3 - float(X) * i = int(Z)Python 3 - 浮点(X) * i = int(Z)
【发布时间】:2016-09-04 18:16:20
【问题描述】:

我有一个非常大的数字,在小数点前后都有,但我只称它为 4.58。

我想知道数字 Y,如果乘以 X 将得到一个整数,而不是任何类型的浮点数。

这是我的代码:

from decimal import *
setcontext(ExtendedContext)
getcontext().prec = 300
x=Decimal('4.58')
while True:
    i=1
    a=Decimal(i*x)
    if float(a).is_integer():
        print(i*x)
        break
    else:
        i=+1

但是,这种方法非常缓慢且效率低下。我想知道如何实现连分数或其他方法来预测 Y 的值?

编辑

十进制模块更准确地存储浮点数(作为字符串),所以 0.5 不会变成 0.499999999。

编辑 2

我有 X (4.58)。

我想知道什么数将乘以 X 得到一个整数;尽可能高效。

编辑 3

好吧,也许还不是我最好的问题。

这是我的困境。

我从我制作的一个小程序中吐出了一个数字。这个数字是十进制数,1.5。

我要做的就是找出哪个整数将乘以我的小数以产生另一个整数。

对于 1.5,最佳答案是 2. (1.5*2=3) (float*int=int)

我上面的while循环最终会做到这一点,但我只是想知道是否有更好的方法来做到这一点,比如连分数;如果有,我该如何实现。

编辑 4

感谢 user6794072,这是我的代码。它很长但很实用。

from gmpy2 import mpz, isqrt
from fractions import Fraction
import operator
import functools
from decimal import *
setcontext(ExtendedContext)
getcontext().prec = 300

def factors(n):
    n = mpz(n)

    result = set()
    result |= {mpz(1), n}

    def all_multiples(result, n, factor):
        z = n
        f = mpz(factor)
        while z % f == 0:
            result |= {f, z // f}
            f += factor
        return result

    result = all_multiples(result, n, 2)
    result = all_multiples(result, n, 3)

    for i in range(1, isqrt(n) + 1, 6):
        i1 = i + 1
        i2 = i + 5
        if not n % i1:
            result |= {mpz(i1), n // i1}
        if not n % i2:
            result |= {mpz(i2), n // i2}
    return result

j=Decimal('4.58')

a=(Fraction(j).numerator)
b=(Fraction(j).denominator)

y=(factors(a))
x=(factors(b))

q=([item for item in x if item not in y])
w=([item for item in y if item not in x]) q.extend(w)

p=(functools.reduce(operator.mul, q, 1)) ans=(p*j)

print(ans)

【问题讨论】:

  • 这是一个罐头蠕虫,因为大多数数字没有精确的 float 表示(例如,0.3 变为 0.299999999999999988897769753748434595763683319091796875)。
  • “我想知道另一个浮点数 Y,如果乘以 X 会得到一个整数,而不是任何类型的浮点数。” - 其他浮点数?你为什么认为这样的浮点数存在,或者它是独一无二的?
  • 顺便说一句,不,decimal 模块确实range 在任何意义上都接受小数。
  • 您确实需要放慢速度并发布有意义的代码。在最新的迭代中,Decimal('x') 只是一个错误 - 你可能指的是 Decimal(x)Decimal(str(x)),但无法猜到是哪个,而且它们根本不一样。跨度>
  • 你想要这个值做什么?你打算用它做什么?你要求的东西没有多大意义,但如果我们知道你想通过使用它来实现什么,我们可能会建议更好的方法来实现它。

标签: python python-3.x loops math floating-point


【解决方案1】:

如果我正确理解您的问题,您希望找到可以乘以非整数 (n) 的最小整数 (i),以便:

i*n 是一个整数

我会通过找到 n 的分子和分母的因数来做到这一点。在您的示例中,如果 n = 4.58,那么您可以提取 458 作为分子,100 作为分母。

458 的倍数是 2 和 229 100的倍数是2、2、5、5

您可以将分子和分母的一个实例划掉 2。那么您的解决方案就是将分母中的剩余因子相乘:在本例中为 2*5*5 或 50。

【讨论】:

  • 非常感谢。我已经在问题中发布了代码。
  • @Master-chip,在对 Mark Dickinson 的评论中,您说您确实想要 50,尽管您没有解释原因。正如@user6794072 在这个答案中所说,如果正确实施,50 也是你从这种方法中得到的答案。一个更简单的方法就是做fractions.Fraction(your_decimal_input).denominator。不需要因式分解 - Fraction() 构造函数自己消除了分子和分母共有的因式(使用 gcd(),比因式分解更有效)。
【解决方案2】:

想想如果你想联系z = 1 然后使用z == z * 1 来扩展答案。对于任何浮点数x != 0.0y = 1/x 将产生z = 1,因此对于任意整数z,只需使用y = z/x

【讨论】:

  • 这实际上不起作用。例如,x=0.013,我们有x*(1/x) != 1decimal 模块可能会更改 x 的特定值作为反例,但它仍然不起作用。
【解决方案3】:

我不是 Python 程序员,但是 round 函数呢?

【讨论】:

  • 不错,但我不想失去准确性。
猜你喜欢
  • 2014-04-23
  • 2013-02-17
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 1970-01-01
  • 2016-02-07
相关资源
最近更新 更多