28.01.2015 Views

Tutorial Python - Starship

Tutorial Python - Starship

Tutorial Python - Starship

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Se întâmplă aşa pentru că numărul de biţi utilizaţi de hardware să mememoreze valoarea în virgulă flotantă variază<br />

de la o maşină la alta, iar <strong>Python</strong> listează doar o aproximaţie zecimală a valorii zecimale reale a aproximaţiei binare<br />

memorată în maşină. Pe majoritatea maşinilor, dacă <strong>Python</strong> va tipări valoarea zecimală reală a aproximaţiei binare<br />

memorate pentru 0.1, va afişa<br />

>>> 0.1<br />

0.1000000000000000055511151231257827021181583404541015625<br />

Prompterul <strong>Python</strong> utilizează funcţia implicită repr() ca să obţină o versiune de şir pentru toate obiectele pe<br />

care le afişează. În cazul numerele flotante repr(float) rotunjeşte valoarea zecimală la 17 digiţi semnificativi,<br />

astfel<br />

0.10000000000000001<br />

repr(float) foloseşte 17 biţi semnificativi pentru că sunt consideraţi suficienţi pe majoritatea maşinilor, aşa că<br />

relaţia eval(repr(x)) == x este exactă pentru toate numerele flotante finite x, dar rotunjirea la 16 biţi nu<br />

este suficientă pentru a face relaţia adevărată.<br />

Acesta este un lucru normal al aritmeticii binare în virgulă flotantă : nu este un bug <strong>Python</strong>, nici un bug al codului<br />

dumneavoastră şi veţi constata o astfel de anomalie în toate limbajele care folosesc aritmetica în virgulă flotantă<br />

oferită de hardware (unele limbaje pot să nu afişeze implicit diferenţa)<br />

Funcţia internă <strong>Python</strong> str() generează numai 12 digiţi semnificativi şi poate că doriţi să o folosiţi modificată.<br />

Este des utilizată funcţia eval(str(x)) pentru a-l obţine pe x, dar este mai placut să se afişeze :<br />

>>> print str(0.1)<br />

0.1<br />

E bine de ştiut că, în sens real, este o iluzie : în maşină valoarea nu este exact 1/10, valoarea adevărată din maşină<br />

este rotunjită la afişare.<br />

Această surpriză este urmata de altele. De exemplu după ce se afişează<br />

>>> 0.1<br />

0.10000000000000001<br />

apare tentaţia să utilizaţi funcţia round() ca să trunchiaţi iarăşi la un digit. Dar aceasta nu face nimic:<br />

>>> round(0.1, 1)<br />

0.10000000000000001<br />

Problema este că valoarea memorată învirgulă flotantă binară pentru "0.1" a fost făcută în cea mai bună aproximare<br />

binară posibilă la 1/10, deci orice altă rotunjire ulterioară nu o poate face mai bine : a fost dată deja cea mai bună<br />

soluţie.<br />

Altă consecinţă a faptului că 0.1 nu este exact 1/10 este aceea că adăugând la 0.1 pe el însuşi de 10 ori nu se obţine<br />

1.0:<br />

>>> sum = 0.0<br />

>>> for i in range(10):<br />

... sum += 0.1<br />

...<br />

fs>>> sum<br />

0.99999999999999989<br />

90 Anexa B. Aritmetica în virgulă flotantă: rezultate şi limitări

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!