2016-09-04 2 views
-4

십진법 전후에 매우 큰 숫자가 있습니다. 그러나 이것을 4.58이라고 부릅니다.파이썬 3 - float (X) * i = int (Z)

X가 곱 해져서 float 번호가 아닌 정수가되는 숫자 Y를 알고 싶습니다.

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) (플로트 *의 INT = INT)

내 위의 루프는 동안 결국,하지만 난 그냥 여부를 알고 싶어, 그렇게 할 것 지속적인 분수와 같은 더 좋은 방법이있었습니다. 있을 경우 어떻게 구현할 수 있습니까?

편집 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) 
+1

대부분의 숫자에는 정확한 'float'표현이 없으므로 웜이됩니다 (예 : '0.3'은 '0.299999999999999988897769753748434595763683319091796875'가됩니다). – NPE

+0

'range'는'float' 값을 허용하지 않습니다. 유효한 예를 제공해주십시오. –

+1

"다른 부동 소수점 숫자, Y를 알고 싶습니다. X가 곱 해져서 부동 소수점 숫자가 아닌 정수가됩니다." * * 다른 부유물? 왜 그런 플로트가 존재한다고 생각합니까, 아니면 독특한 것입니까? – user2357112

답변

1

내가 제대로 질문을 이해한다면, 당신은 가장 작은 정수가 아닌 수 (N)로 곱한 수의 정수 (I) 그래서 찾으려 :

내가 N *은 정수

입니다

나는 n의 분자와 분모의 인자를 찾아서 이것을 할 것입니다. 귀하의 예제에서, n = 4.58이면, 분자에 대해 458을 그리고 분모에 대해 100을 추출 할 수 있습니다. 458의

배수는 100의 2, 229 배수가 2, 2, 5, 5

당신은 분자와 분모에 대한 2의 인스턴스를 교차 할 수 있습니다 있습니다. 그런 다음 분모의 나머지 요소를 곱하면됩니다.이 경우 2 * 5 * 5 또는 50입니다.

+0

고마워요. 질문에 코드를 게시했습니다. –

+1

@ Master-Chip, Mark Dickinson에 대한 논평에서, 당신은 당신이 이유를 설명하지 않았지만 당신이 50을 원하지 않는다고 말했습니다. @ user6794072가이 대답에서 말했듯이, 올바르게 구현된다면 50도이 접근법에서 얻는 답입니다. 그것을 얻는 훨씬 쉬운 방법은'fractions.Fraction (your_decimal_input) .denominator'입니다. 인수 분해는 필요하지 않습니다.'Fraction()'생성자는 분자와 분모에 공통적 인 요소를 모두 제거합니다 ('gcd() '를 사용하여 인수 분해보다 훨씬 효율적입니다). –

0

그럼 당신이 z = 1에 도달 한 후 z == z * 1 답변을 확장 할 수 있다는 사실을 사용하기를 원한다면 무엇을 생각합니다. 모든 float에 대해 x != 0.0, y = 1/xz = 1이 될 것이므로 임의의 정수 z의 경우 y = z/x을 사용하십시오.

+0

이것은 실제로 작동하지 않습니다. 예를 들어'x = 0.013'을 사용하면'x * (1/x)! = 1'이됩니다. 'decimal' 모듈은'x'의 특정 값이 반례식일지도 모르는 것을 바꿀 수 있습니다. 그러나 여전히 작동하지 않을 것입니다. – user2357112

0

저는 파이썬 프로그래머가 아니지만, round은 어떤 기능을합니까?

+0

좋은 점이 있지만 정확성을 잃고 싶지는 않습니다. –

관련 문제