Topic: [RISOLTO]: PROBLEMI CON LE DIVISIONI  (Letto 74 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Pitone62

  • python unicellularis
  • *
  • Post: 3
  • Punti reputazione: 0
    • Mostra profilo
[RISOLTO]: PROBLEMI CON LE DIVISIONI
« il: Agosto 28, 2020, 23:32 »
Ciao a tutti!
Premetto che non sono un programmatore, che ho appena iniziato a studiare Python e mi sono iscritto a questo forum solo da qualche giorno.
Abbiate quindi pazienza e perdonatemi sin d'ora se non sono molto chiaro nel presentare il problema che ho incontrato.

Stavo giocherellando con la shell di Python 3.8.5 e provavo a scrivere semplici comandi e a fagli eseguire semplici operazioni matematiche
quando mi sono accorto che, dividendo un numero non intero per una potenza di dieci, alle volte ottengo un risultato non corretto.

Forse mi spiego meglio con degli esempi dalla shell per Windows 7:

Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.

>>> 423.321/100
4.233210000000001

>>> 56595.6549269/10000
5.6595654926900005

Questo però non succede sempre, infatti:

>>> 423.321/1000
0.423321

>>> 791.463/100
7.91463

Provando con alcune versioni presenti online, ho appurato che il problema si manifesta solo con Python 3.X.X 
mentre se uso Python 2.7.X il risultato è sempre giusto.

Ho cercato di capire anche se il problema potesse essere causato dal diverso formato tra 423.321 che è un float e 100 che è un int
ma anche convertendo 100 in float il risultato non cambia:

Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>>
=================== RESTART: C:/Users/XXX/Desktop/div.py

===================
423.321 <class 'float'>
100 <class 'int'>
4.233210000000001 <class 'float'>
>>>
=================== RESTART: C:/Users/XXX/Desktop/div1.py

===================
423.321 <class 'float'>
100.0 <class 'float'>
4.233210000000001 <class 'float'>
>>>

Sbaglio io qualcosa? Facile per la mia età ma se il problema è reale, potrebbe affliggere anche altri tipi di operazioni matematiche.

Voi che ne pensate?
Grazie fin d'ora per le eventuali risposte.
PY62
« Ultima modifica: Agosto 29, 2020, 18:02 da Pitone62 »

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.083
  • Punti reputazione: 9
    • Mostra profilo
Re:PROBLEMI CON LE DIVISIONI
« Risposta #1 il: Agosto 29, 2020, 11:12 »
https://docs.python.org/3/tutorial/floatingpoint.html
o adesso anche in italiano, visto che qualcuno (!) ha tradotto il tutorial in italiano:
https://pytutorial-it.readthedocs.io/it/python3.8/floatingpoint.html

Offline Pitone62

  • python unicellularis
  • *
  • Post: 3
  • Punti reputazione: 0
    • Mostra profilo
PROBLEMI CON LE DIVISIONI
« Risposta #2 il: Agosto 29, 2020, 18:00 »
https://docs.python.org/3/tutorial/floatingpoint.html
o adesso anche in italiano, visto che qualcuno (!) ha tradotto il tutorial in italiano:
https://pytutorial-it.readthedocs.io/it/python3.8/floatingpoint.html

Gentilissimo RicPol, grazie per la cortese e paziente risposta chiarificatrice riguardo le "imprecisioni" della virgola mobile!    :)
Avevo cercato con Google e nel forum senza ricordarmi di cercare nei docs di Python (comunque probabilmente non avrei trovato nulla, perché non usavo le giuste chiavi di ricerca).   :(

Mi resta solo una curiosità: perché mi succeda con Python 3.X.X e non con Python 2.7.X    :question:
Citando il link in italiano che hai inserito tu (essendo tua la traduzione ho un ulteriore motivo per ringraziarti!), leggo:
"Molti anni fa, il prompt di Python e la funzione predefinita repr() sceglievano tra le possibili rappresentazioni quella con 17 cifre significative, 0.10000000000000001.
A partire da Python 3.1, sulla maggior parte delle piattaforme Python è in grado di scegliere quella più breve e visualizza semplicemente 0.1.
"
Per cui, se non capisco male quanto scritto sopra, dovrebbe essere più facile che il problema si presenti nelle versioni più vecchie piuttosto che in quelle più nuove come la 3.8.5 che uso io.

Ti ringrazio in anticipo per l'eventuale risposta .
 :py: Py62
« Ultima modifica: Agosto 29, 2020, 18:02 da Pitone62 »

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.083
  • Punti reputazione: 9
    • Mostra profilo
Re:[RISOLTO]: PROBLEMI CON LE DIVISIONI
« Risposta #3 il: Agosto 29, 2020, 18:46 »
stai confondendo due cose diverse. Il segno "/" in python3 vuol dire un'altra cosa che in python2... https://docs.python.org/3/whatsnew/3.0.html#integers

Offline Pitone62

  • python unicellularis
  • *
  • Post: 3
  • Punti reputazione: 0
    • Mostra profilo
Re:[RISOLTO]: PROBLEMI CON LE DIVISIONI
« Risposta #4 il: Settembre 16, 2020, 23:02 »
stai confondendo due cose diverse. Il segno "/" in python3 vuol dire un'altra cosa che in python2... https://docs.python.org/3/whatsnew/3.0.html#integers

Si avevo visto anche io che tra py2 e py3 ci sono delle differenze non trascurabili e avevo visto anche questo sito https://okpanico.wordpress.com/2011/09/12/python-differenze-fra-le-versioni-2-e-3/ dove dice:

In py2 la divisione fra interi ritorna un intero troncando il risultato. Per avere un float si deve avere almeno un float ( o fare un cast). In py3 la divisione ritorna un float, anche se il risultato è un intero. Esiste l’operatore // che si comporta come / in py2.

Python 2: 4/3 # result is 1
Python 2: 3/3 # result is 1
Python 2: 4.0/3 # result is 1.33333 (il dividendo è un float e quindi il risultato è un float)
Python 2: 3.0/3 # result is 1.0
Python 3: 4/3 # result is 1.33333 (qui il risultato è sempre un float indipendentemente da dividendo e divisore)
Python 3: 3/3 # result is 1.0
Python 3: 4//3 # result is 1
Python 3: 3//3 # result is 1


Siamo quindi nei casi che ho sottolineato qui sopra e questo, da solo, non spiega perché in py2
>>> 423.321/100
4.23321
mentre in py3
>>> 423.321/100
4.233210000000001
Ha senso solo con la motivazione da te suggerita ovvero le "imprecisioni" della virgola mobile dovute alla memorizzazione in forma binaria.