Topic: Oracle lettura record compaiono 15 decimali in alcuni valori  (Letto 89 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline dangr

  • python unicellularis
  • *
  • Post: 1
  • Punti reputazione: 0
    • Mostra profilo
Buongiorno a tutti,
mi sono cimentato in un piccolo programma python che legge i dati da Oracle.
Ho utilizzato cx_Oracle dal sito: https://cx-oracle.readthedocs.io/en/latest/
il pc client e' in ambiente windows 10
Nel programma utilizzo un comando del tipo:
curs0="select NUM_DISTG, numassegno,impo_totma from file01 where...."
buf1=curs1.fetchall() # lista
 buf0=(*buf1,)   
print ("buf0---> ", buf0)

mi produce un output del tipo:
buf0 --->  ( (486, 5913, 1509.8700000000001), (496, 5914, 50.28), (452, 5915, 780.19), (486, 5917, 1565.1100000000001), (486, 5919, 6461.610000000001), (486, 5921, 2604.25), (486, 5923, 2140.2), (486, 5925, 1489.81), (486, 5927, 5589.26), (486, 5929, 2736.48), (486, 5931, 1219.64), (486, 5933, 2426.06), (486, 5935, 1460.92), (486, 5937, 3456.63), (487, 5939, 3335.33), (487, 5941, 35141.86), (487, 5943, 2817.9), (487, 5945, 6248.4800000000005),.......

Ossia l'importo ogni tanto ha un valore con un numero alto di decimali tipo 1509.8700000000001
mentre se faccio la stessa istruzione su toad la questione non si propone.
Tuttavia non riesco a capire se dipende dalla libreria, oppure ho omesso qualche dichiarazione

Grazie a chiunque vorra' rispondere

Offline nuzzopippo

  • python habilis
  • **
  • Post: 67
  • Punti reputazione: 0
    • Mostra profilo
Re:Oracle lettura record compaiono 15 decimali in alcuni valori
« Risposta #1 il: Luglio 25, 2019, 12:37 »
Ciao

Pur non conoscendo la struttura dei dati in questione, mi sembra molto probabile che il problema si individui nella imprecisione della rappresentazione dei numeri in virgola mobile in binario, in effetti, tale rappresentazione è approssimata.
un piccolo esempio in merito :

>>> var = 0.0
>>> for i in range(20):
var += 0.01
print(var, end=' ')


0.01 0.02 0.03 0.04 0.05 0.060000000000000005 0.07 0.08 0.09 0.09999999999999999 0.10999999999999999 0.11999999999999998 0.12999999999999998 0.13999999999999999 0.15 0.16 0.17 0.18000000000000002 0.19000000000000003 0.20000000000000004


La soluzione, di per se, è semplice, basta tener presente il problema ed arrotondare i dati alla massima precisione voluta

>>> var = 0.0
>>> for i in range(20):
var += 0.01
print('%.2f' %(var), end=' ')


0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.10 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.20


Il problema è presente in tutti i sistemi operativi ed in tutti i linguaggi di programmazione, tenerlo presente e rimediare preventivamente è l'unica soluzione.

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 2.870
  • Punti reputazione: 9
    • Mostra profilo
Re:Oracle lettura record compaiono 15 decimali in alcuni valori
« Risposta #2 il: Luglio 25, 2019, 21:13 »
dovresti guardare qual è il tipo di quel campo, e controllare come cx_oracle gestisce quel tipo... ovvero, probabilmente male a giudicare dal risultato (sì, nel dettaglio potrebbe in effetti essere un problema di aritmetica float come ti è stato detto...). D'altra parte, ovviamente toad non avrà problemi essendo un tool specializzato per oracle.
Poi insomma, vedrei se esiste una soluzione più "istituzionale" prima di mettermi a fare arrotondamenti a mano: per esempio registrare un adapter per il tipo in questione, vedere se cx_oracle ha delle estensioni che coprono quel tipo, vedere se esistono altri driver di database per oracle che fanno la cosa giusta... Non ho mai usato oracle quindi non saprei consigliarti...

Offline GlennHK

  • python sapiens sapiens
  • ******
  • Post: 1.654
  • Punti reputazione: 1
    • Mostra profilo
    • La Tana di GlennHK
Re:Oracle lettura record compaiono 15 decimali in alcuni valori
« Risposta #3 il: Luglio 29, 2019, 22:11 »
Mai usare tipi floating point per degli importi.


Usa il tipo decimal.