2015-02-04 5 views
1

나는 파이썬 2.7이 릴리스 된 직후부터 사용 해왔다. 나는 최근에 2.7에 문제가있어서 필요한 모든 것을하지 않았기 때문에 마지막으로 업데이트했다. 그러나, 며칠 후, 나는 곱셈과 관련된 몇 가지 문제에 주목하고 있습니다. 하지만 내가하고있는 일이나 파이썬 자체에 문제가 있습니까?파이썬 곱셈 오류 (버전 3.4)

>>> 12*0.1 
1.2000000000000002 

이 같은 루프 실행하는 경우 :

>>> for i in range (-20, 20): 
...  print (i, i*.1) 
... 

출력은을 :

-20 -2.0 
-19 -1.9000000000000001 
-18 -1.8 
-17 -1.7000000000000002 
-16 -1.6 
-15 -1.5 
-14 -1.4000000000000001 
-13 -1.3 
-12 -1.2000000000000002 
-11 -1.1 
-10 -1.0 
-9 -0.9 
-8 -0.8 
-7 -0.7000000000000001 
-6 -0.6000000000000001 
-5 -0.5 
-4 -0.4 
-3 -0.30000000000000004 
-2 -0.2 
-1 -0.1 
0 0.0 
1 0.1 
2 0.2 
3 0.30000000000000004 
4 0.4 
5 0.5 
6 0.60000000000000001 
7 0.70000000000000001 
8 0.8 
9 0.9 
10 0.10 
11 0.11 
12 0.120000000000000002 
13 0.13 
14 0.140000000000000001 
15 0.15 
16 0.16 
17 0.170000000000000002 
18 0.18 
19 0.190000000000000002 

나는 그러나이 같은 루프를 수행 할 때 :

>>> for i in range (-20, 20): 
...  print (i, i/10) 
... 

을 올바른 숫자가 인쇄됩니다. 나는 심지어 첫 번째 루프를 +/- 1,000,000의 범위로 돌렸고, 숫자의 약 40 %가 이런 식으로 끝납니다. 왜 이런 일이 일어나는 걸까요?

+0

플로트는 본래부터 정확하지 않습니다. 정확한 결과를 원하면'fractions' 모듈을 고려하십시오. – Kevin

+0

3.x, btw와 관련이 없습니다. 나는 2.7에서 당신의 코드를 시도 할 때'1.2000000000000002'를 얻는다. – Kevin

+1

[부동 소수점 연산이 깨졌습니까?] (http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – MattDMo

답변

2

차이점은 정수는 2 진수로 정확하게 나타낼 수 있지만 많은 십진수는 (유한 메모리가 주어질 수는 없음).

>>> "%.32f" % 0.1 
'0.10000000000000000555111512312578' 

그것은 정확히0.1 아니다 :

플로트 0.1이의 예입니다. 부동 소수점 0.1을 곱하면 10으로 나누는 것과 같지 않습니다. 물론

>>> 14/10 
1.4 
>>> 14 * 0.1 
1.4000000000000001 

가 여기에도 결과가 정확히 1.4입니다 그것은 플로트 0.1에 의한 곱셈은 정수 10로 나누어 이상의 오류가 약간 더 여유가있는 단지입니다 : 당신이 관찰 그것은 다른 결과를 제공합니다. 이 둘의 차이점은 소수점 이하 자릿수가 반올림 될만큼 충분하지만 곱셈은 반올림되지 않습니다.

0

문제는 파이썬에서 floating point입니다. 이 링크에서 읽을 수 있듯이 실제로 숫자가 많기 때문에 파이썬은 숫자를 반올림하는 데 사용합니다. 당신은 그러나 10

으로 나눌 때, 이잖아 부동 소수점 수를보고 SPECT 0.1 파이썬 asumes에 의해 multipli이 문제가 발생하지 않는 이유를 할 때, 당신은 당신이 원하는 경우 숫자를 포맷 할 수 있습니다

>>> format(math.pi, '.12g') # give 12 significant digits 
'3.14159265359' 

>>> format(math.pi, '.2f') # give 2 digits after the point 
'3.14' 

희망이 도움이됩니다.

+0

문제가 * python에 있지 않다는 것을 분명히해야합니다 *하지만 모든 현대 프로세서에서 사용되는 것처럼 부동 소수점이 작동하는 방식입니다. – jepio