Python 3 - float(X) * i = int(Z)
<p>I have a very large number, both before and after the decimal, but for this I'll just call it 4.58.</p>

<p>I want to know the number, Y, that will yield me an integer if multiplied by X and not any sort of float number.</p>

<p>Here is my code:</p>

<pre><code>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
</code></pre>

<p>However, this method is incredibly slow and inefficient. I was wondering how could I implement continued fractions or some other method to make it predict the value of Y?</p>

<p><em>Edit</em></p>

<p>The decimal module stores float numbers more accurately (As strings), so 0.5 <em>won't</em> become 0.499999999.</p>

<p><em>Edit 2</em></p>

<p>I've got X (4.58).</p>

<p>I want to know what number will multiply by X to make an integer; as efficiently as possible.</p>

<p><strong>Edit 3</strong></p>

<p>Okay, maybe not my best question yet.</p>

<p>Here's my dilemma.</p>

<p>I've got a number spat out from a trivial programme I made. That number is a decimal number, 1.5.</p>

<p>All I want to do is find what integer will multiply by my decimal to yield another integer.</p>

<p>For 1.5, the best answer will be 2. (1.5*2=3) (float*int=int)</p>

<p>My while-loop above will do that, eventually, but I just wanted to know whether there was a better way to do this, such as continued fractions; and if there was, how could I implement it.</p>

<p><em>Edit 4</em></p>

<p>Here's my code thanks to user6794072. It's lengthy but functional.</p>

<pre><code>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)
</code></pre>

<p>Well think of what if you wanted to reach <code>z = 1</code> and then use the fact that <code>z == z * 1</code> to scale the answer. For any float <code>x != 0.0</code>, <code>y = 1/x</code> will yield <code>z = 1</code>, so for arbitrary integer <code>z</code>, just use <code>y = z/x</code>.</p>

python python-3.x loops math floating-point