Sottrazione tra numeri decimali "errata"

di il
3 risposte

Sottrazione tra numeri decimali "errata"

Ho un programma PHP che interroga un database MySql chiedendogli di fare la somma del campo importo (decimal(15,2)) di spese e di entrate separatamente in un determinato arco di tempo.
per esempio somma uscite dal 1.1.2012 al 1.9.2016
per esempio somma entrate dal 1.1.2012 al 1.9.2016

Quando sottraggo uscite-entrate mi ritorna un numero tipo 12.450000000021 oppure 12.450000000001
0000000021 o 0000000001 non ci dovrebbero essere dato che sottraggo due numeri che hanno 2 decimali dopo la virgola (punto per MySql).
Se guardo il numero con le solo prime due cifre decimali la sottrazione è corretta.

se cambio l'arco temporale aggiungendo un mese per esempio dal 1.1.2012 al 1.10.2016
i decimali in eccesso spariscono. Se continuo ad aggiungere tempo i decimali in maniera random uno, due, tre o più mesi dopo tornano. Non rispettano una sequenza comprensibile.

Quello che mi fa impazzire è che aggiungo sempre dati alle somme e gli errori (se di errori si tratta) penso che dovrebbero accumularsi non sparire e poi ripresentarsi senza un apparente motivo.

Ho preso i valori di entrata e uscite e gli ho dato un $uscite=(float)$uscite prima di sottrarli e quando gli chiedo il gettype($entrate) mi risponde double ma niente è cambiato.

Ho preso le entrate e gli ho sottratto una variabile tipo $varnumerica=1000.34 impostata da me per capire se il problema era la somma delle entrate o delle uscite e ho scoperto che il risultato è perfetto cioè con due soli decimali
Ho allora ho fatto anche il contrario, ho preso le uscite e le ho sottratte alla stessa variabile e il risultato è perfetto cioè con due soli decimali

Che altro potrei tentare prima di fare un format_number($num, 2, '.', '') ??????
Anche perchè mi piacerebbe capire cosa succede ....

3 Risposte

  • Re: Sottrazione tra numeri decimali "errata"

    Se può essere utile:
    quando nella query chiedo direttamente a MySql di fare il SUM() i decimali sono 0000000001
    se invece faccio un select e poi sommo con un foreach in php fogliando i valori delle tuple ottengo un decimale 00000000021
  • Re: Sottrazione tra numeri decimali "errata"

    marybeth74 ha scritto:


    Ho un programma PHP che interroga un database MySql chiedendogli di fare la somma del campo importo (decimal(15,2)) di spese e di entrate separatamente in un determinato arco di tempo.
    per esempio somma uscite dal 1.1.2012 al 1.9.2016
    per esempio somma entrate dal 1.1.2012 al 1.9.2016

    Quando sottraggo uscite-entrate mi ritorna un numero tipo 12.450000000021 oppure 12.450000000001
    0000000021 o 0000000001 non ci dovrebbero essere dato che sottraggo due numeri che hanno 2 decimali dopo la virgola (punto per MySql).
    Se guardo il numero con le solo prime due cifre decimali la sottrazione è corretta.

    se cambio l'arco temporale aggiungendo un mese per esempio dal 1.1.2012 al 1.10.2016
    i decimali in eccesso spariscono. Se continuo ad aggiungere tempo i decimali in maniera random uno, due, tre o più mesi dopo tornano. Non rispettano una sequenza comprensibile.

    Quello che mi fa impazzire è che aggiungo sempre dati alle somme e gli errori (se di errori si tratta) penso che dovrebbero accumularsi non sparire e poi ripresentarsi senza un apparente motivo.

    Ho preso i valori di entrata e uscite e gli ho dato un $uscite=(float)$uscite prima di sottrarli e quando gli chiedo il gettype($entrate) mi risponde double ma niente è cambiato.

    Ho preso le entrate e gli ho sottratto una variabile tipo $varnumerica=1000.34 impostata da me per capire se il problema era la somma delle entrate o delle uscite e ho scoperto che il risultato è perfetto cioè con due soli decimali
    Ho allora ho fatto anche il contrario, ho preso le uscite e le ho sottratte alla stessa variabile e il risultato è perfetto cioè con due soli decimali

    Che altro potrei tentare prima di fare un format_number($num, 2, '.', '') ??????
    Anche perchè mi piacerebbe capire cosa succede ....
    Per capire il perche' di questi strani decimali, ci sono corsi semestrali all'universita', il che implica che la spiegazione richiede un bel po' di concetti sofisticati.

    Comunque, il problema fondamentale e' il seguente: le operazionei NON VENGONO FATTE IN BASE 10, MA IN BASE 2, ed in base 2 non tutti i numeri con un numero FINITO DI DECIMALI (quindi rappresentato in 10) possono essere PERFETTAMENTE RAPPRESENTATI.

    Ed infatti, per fare questo tipo di operazioni si usano numeri in rappresentazione BCD (binary coded decimal) a FIRGOLA FISSA.

    Ma anche in questo caso, la gestione dei decimali E' TUTT'ALTRO CHE BANALE.

    Se vuoi andare piu' in dettaglio, dei prenderti un libro sul Calcolo Numerico
  • Re: Sottrazione tra numeri decimali "errata"

    Quindi mi consigli di rinunciare e fare un format_number ???
Devi accedere o registrarti per scrivere nel forum
3 risposte