2016-07-03 2 views
3

파이썬 3.52에서 float 유형에서 분수 유형으로 변환하는 주제에 대해 연습하면서 2 가지 다른 변환 방법의 차이점을 발견했습니다.파이썬에서 소수 변환으로 플로트

첫 번째 방법은 다음과 같습니다

>>> from fractions import Fraction 
>>> x = 1232.23 
>>> f = Fraction(*x.as_integer_ratio()) 
>>> print(f) 
2709702426188841/2199023255552  #Answer 

두 번째 방법은 다음과 같습니다

>>> from fractions import Fraction 
>>> x = 1232.23 
>>> f = Fraction(str(x)) 
>>> print(f) 
123223/100       #Answer 

나는이 두 가지 다른 대답 뒤에 이유를 알고 싶어? 죄송합니다. 어리석은 질문이라면 프로그래밍과 파이썬을 처음 접했습니다.

편집 :

>>> from fractions import Fraction 
>>> x = 1232.23 
>>> f = Fraction(*x.as_integer_ratio()) 
>>> f = f.limit_denominator(100)  
>>> print(f) 
123223/100 

답변

4

부동 소수점 숫자는 10 진수 (10 진수)로 저장되지 않지만 2 진수 (2 진수)로 저장되기 때문입니다.

10 진수의 유한 길이 숫자는 2 진수의 반복되는 십진수가 될 수 있습니다. 그리고 부동 소수점은 고정 된 크기이기 때문에 반복되는 소수점이 잘 리면 부정확하게됩니다.

as_integer_ratio을 2 진수의 반복 소수점 숫자로 사용하면 기본 -10에서 2 진수 변환의 약간의 부정확 한 결과로 다소 어리석은 부분을 얻을 수 있습니다. 이 두 숫자를 나눌 경우 값은 원래 숫자에 매우 가깝습니다.

예를 들어, 밑이 10 인 경우 1/10 = 0.1이지만 반복 소수가 아닌 경우 실제로는 밑이 -2 인 경우 반복되는 십진수입니다. 10 분의 1에서 1/3 = 0.333과 같습니다.

>>> (0.1).as_integer_ratio() 
(3602879701896397, 36028797018963968) 

파이썬의 출력이 정확한라면 당신은 출력으로 1.00000 같은 ... 01 공격자의 프롬프트에서 단지 0.1를 입력 할 경우에도, 당신이 볼 것입니다. 그러나 파이썬 은 일반적인 경우에 당신에게서이 부정확 한 것을에 숨겨 혼란을 낳습니다.

+0

좀 더 정확한 대답처럼 보입니다. 이것이이 아나몰리의 이유일까요? '>>> 0.1 + 0.1 + 0.1-0.3' '5.551115123125783e-17' –

+0

@AbdulHaseeb : 그 이유는 사실이 아닙니다. 왜냐하면 제가 설명했듯이,베이스에서 십진수를 반복하지 않고도 표현할 수있는 숫자는, 10은 base-2에있을 수있는 것과 다릅니다. –

2

이 실제로 꽤 좋은 질문이다 : 나는 limit_denominator 방법으로 정확한 먼저 방법으로 얻은 부정확 한 부분을 변환 할 수있는 방법을 발견했다. 다른 결과의 이유는 1232.23에 대한 정확한 float 표현이 없기 때문에 이 실제로 1232.23이 아니기 때문에 1232.23의 가장 가까운 float 표현의 부분 표현은 2709702426188841/2199023255552입니다. 그러나 str(1232.23)을 사용하면 정확히 1232.23으로 처리합니다 숫자의 진정한 최상의 분수 표현을 반환합니다.