2012-08-08 2 views
0

가능한 중복 : 코드에서
python - decimal place issues with floats
Python float equality weirdness파이썬 이상한 또한 버그

내가 떠있는 변수 percentage이 아래. 나는 그것이 number에 도달하면 10,000에 도달하도록 percentage이 올라가도록 .01으로 설정하도록 설정했습니다.

# Tries to find a number that when squared and 5%'ed is still a square. 

import math 

print("Script has started:\n") 

percentage = .1 
number = 1 
while number != -1: 
    number = number + 1 
    num_powered = number ** 2 
    num_5per = num_powered * percentage 
    num_5per_sqrt = math.sqrt(num_5per) 
    num_list = list(str(num_5per_sqrt)) 
    dot_location = num_list.index(".") 
    not_zero = 0 
    for x in num_list[dot_location + 1:]: 
     if x != "0": 
      not_zero = 1 
      break 
    if not_zero == 0: 
     print("*********************************") 
     print("Map :",number) 
     print("Safe-Area :",num_5per_sqrt) 
     print("Percentage :",percentage) 
     print("*********************************") 
     input() 

    if number > 10000: 
       number = 0 
       percentage = percentage + .01 
       print(percentage) 

출력 : 당신은 부동 소수점 숫자를 사용하고 representation error을 경험 한

0.11 
0.12 
0.13 
0.14 
0.15000000000000002 # Here is where it goes crazy 
0.16000000000000003 
+4

이것은 매우 일반적입니다. 컴퓨터의 부동 소수점 숫자는 기본 2이며 기본 10에 자연스러운 숫자를 정확하게 나타낼 수 없습니다. –

+3

이것은 버그가 아닙니다. 부동 소수점 변수가 작동하는 방식의 결과입니다. http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html을 참조하십시오. 중복으로 투표를 종료합니다. –

+0

오, 감사합니다. 죄송합니다. 검시되었지만 중복 된 것을 보지 못했습니다. – RandomPhobia

답변

11

이 이진 부동 소수 점수의 본성에 있음을 the Python docs

주에서이 파이썬에서 하지 버그이며, 코드 (강조 광산) 중 하나에서 버그가 아닙니다 .당신은 아마 the decimal module를 사용해야합니다

있습니다 (일부 언어는 기본적으로 차이가 표시되지 않을 수 있지만, 또는 모든 출력 모드에서) 하드웨어의 부동 소수점 연산을 지원하는 모든 언어에서 같은 종류의 문제를 볼 수 있습니다.

+4

그 링크는 현상에 대한 믿을 수 없을 정도로 멋진 설명입니다. 전에는 본 적이 없었습니다. 나는 여전히 혼란스러워하는 누군가가 그것을 완전히 읽어야한다고 제안한다. –

6

. 특히, 0.01는 2 진 부동 소수점 숫자로 정확한 표현을 갖지 않습니다. 대신에 매우 가까운 숫자이지만 0.01과 정확히 같지 않은 숫자가 저장됩니다. 이것은 버그가 아닙니다. 이것은 부동 소수점 연산이 작동하는 방식입니다.

몇 가지 방법으로 문제를 해결할 수 있습니다.

  • 결과가 정확하지 않은 것을 수락 또는 정수를 100 일해서
  • 곱하기 모든 것을 나
  • 사용 Decimal 유형입니다.

예 :

from decimal import Decimal 
percentage = Decimal('0.1') 
step = Decimal('0.01') 
percentage += step 
+1

+1이 문제를 해결하는 일반적인 방법의 목록입니다. –

0

수레 무한 정밀도를 가지고 있지 않으며, 그래서 당신은 이런 이상한 행동을 얻는다.

보다 나은 해결책은 백분율을 10 진수로 나타내고 1 씩 증가시켜 정수로 저장하는 것입니다.

예 :

percent_as_integer += 1 

대신

percent_as_float += 0.01 

당신이 비율을 표시 할 때, 단순히 수행

print "%d.%02d" % divmod(percent_as_integer, 100) 

편집 : 사실, 소수 모듈 대신 등을 사용하여 다른 대답은 아마 더 나은, pythonic 솔루션입니다 제안했다.

0

다른 답변에서 설명한 것처럼 이것은 현재의 모든 마이크로 프로세서에서 기본 부동 소수점 숫자의 제한 사항입니다.

십진수의 정확한 표현 (예 : 회계 및 비즈니스 응용 프로그램)이 필요하면 부동 소수점이 아닌 decimal 유형을 사용해야합니다. 십진 형식의 고성능 구현 인 cdecimal 모듈을 사용할 수도 있습니다.