Italian Gestione numeri numerici e numeri stringhe

Vasmar

Member
Licensed User
Buonasera,
nell'app avrei bisogno di manipolare dei numeri (aggiungere/togliere cifre o virgola) per cui gestisco un numero in formato String e poi per fare di conto lo sposto in una variabile Float (e viceversa). Il problema che incontro è che se ho nella variabile String il numero "2.3", quando lo porto nella variabile Float diventa 2.299999952316284.
Qualcuno ha una idea del perché e, soprattutto, del come evitare ciò?
Infiniti grazie.
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Per risolvere il problema devi usare Double al posto di Float

Il "perchè" è noto ormai da quarant'anni, è come viene gestito il tipo float all'interno del microprocessore, e cioè con una parte che si chiama mantissa e una parte che si chiama esponente, prova a cerca su internet, trovi di sicuro un sacco di info.

Il tipo Double ha comunque lo stesso problema, ma si nota molto molto meno perchè ha una precisione più elevata del tipo Float, per cui dovresti risolvere il tuo problema.
In VB.NET è stato introdotto il tipo Decimal che utilizza altri sistemi e quindi è proprio adatto a calcoli finanziari dove la precisione non deve essere assolutamente persa, ma in B4X non esiste un tipo di dato primitivo, per cui la soluzione su B4X è di utilizzare eventualmente la libreria BigDecimal, assolutamente più precisa ma più lenta.

Prova con Double e poi facci sapere

Mi ha incuriosito quel "aggiungere/togliere cifre o virgola", non sono cose che riesci a fare comunque con un tipo numerico senza passare per il tipo stringa ??

Sergio
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Per risolvere il problema devi usare Double al posto di Float

Il "perchè" è noto ormai da quarant'anni, è come viene gestito il tipo float all'interno del microprocessore, e cioè con una parte che si chiama mantissa e una parte che si chiama esponente, prova a cerca su internet, trovi di sicuro un sacco di info.

Il tipo Double ha comunque lo stesso problema, ma si nota molto molto meno perchè ha una precisione più elevata del tipo Float, per cui dovresti risolvere il tuo problema.
In VB.NET è stato introdotto il tipo Decimal che utilizza altri sistemi e quindi è proprio adatto a calcoli finanziari dove la precisione non deve essere assolutamente persa, ma in B4X non esiste un tipo di dato primitivo, per cui la soluzione su B4X è di utilizzare eventualmente la libreria BigDecimal, assolutamente più precisa ma più lenta.

Prova con Double e poi facci sapere

Mi ha incuriosito quel "aggiungere/togliere cifre o virgola", non sono cose che riesci a fare comunque con un tipo numerico senza passare per il tipo stringa ??

Sergio
Il decimal di VB per evitare questi problemi usa alcuni bit per rappresentare la cifra intera e altri Beats per rappresentare il valore decimale.
Quindi la rappresentazione numerica è sempre corretta.

Alcuni o emulano questo sistema usando gli interi e considerando le ultime due cifre come se fossero decimali. Come dire che il risultato è rappresentato a schermo viene diviso per 100 però il numero viene elaborato come se fosse un intero
 

Vasmar

Member
Licensed User
🙏 Grazie per le spiegazioni esaustive.
Per Sirjo66, il motivo di quel "aggiungere/togliere cifre o virgola" è che sto imparando e per ora faccio cose semplici, in particolare sto facendo una calcolatrice. App inutile in quanto ne esistono almeno migliaia, ma per esercitarmi e imparare va bene. Se l'utente toglie la cifra di destra di un decimale, non so come fare senza passare per la stringa.
Ho provato a definire tutte le variabili come Double e il problema è diminuito ma non estinto. Ho sottratto 8,214 a -3,2 e il risultato è stato -11.414000000000001
Mi chiedo come facciano le app "calcolatrici" che già esistono.
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Un piccolo trucco potrebbe essere usare gli integer, o, nel tuo caso, meglio ancora un long.
Prima di tutto devi trovare tra il 8,214 e -3,2 quale dei due numeri ha più cifre decimali, ovviamente sarà 8,214 che ha 3 cifre decimali.
Adesso fai 10 elevato a 3 (cioè il 3 che hai trovato prima) e ti viene fuori 1000
Moltiplichi tutti e due i numeri per 1000, e ti ritrovi 8214 e -3200
Adesso fai -3200-8214 e avrai -11414
Dividi di nuovo per 1000 e ti ritrovi -11,414
Ma credo comunque che poi, essendo un problema di mantissa ed esponente, il problema è lo stesso.
Hai provato ad usare la libreria BigDecimal ??
 

Vasmar

Member
Licensed User
Sì, può essere una buona idea quella di trattarli come interi. mi pare che il problema si presenti con i decimali... grazie.
La libreria BigDecimal non la conosco... ora chiedo a ChatGpt ;)
 

Vasmar

Member
Licensed User
Comunque, detto tra noi, da vecchio informatico, trovo semplicemente folle che un microprocessore mi restituisca un numero sbagliato in una operazione, logica o numerica che sia! :eek:
 

pixet

Member
Licensed User
Longtime User
Ho spesso lo stesso problema anch'io e l'ho risolto utilizzando una funzione che formatta il numero che gli passo, un po come
si faceva una volta con il "PRINT USING string expressions;list of expressions".
la funzione è disponibile in B4J/B4A/B4i/B4R "NumberFormat" oppure "NumberFormat2"
In allegato ho messo un file che utilizza questo metodo che uso in alcune app di contabilità dove
imposto il numero minimo di cifre per la parte intera e quante cifre decimali voglio rappresentare.

PS:
Per chi non lo ricordasse la programmazione esisteva anche ai tempi dei "dinosauri", e oltre al linguaggio macchina esistevano anche linguaggi "evoluti"
ad esempio Assembler, Cobol, Fortran, Lisp, Pascal, etc, e il "GWBASIC".
 

Attachments

  • prova_decimali.zip
    2.5 KB · Views: 32
Last edited:

Vasmar

Member
Licensed User
Cosa mi ricordi! Ho lavorato molti anni in Assembler, Cobol e Natural (un linguaggio nativo di Adabas, un DBMS relazionale).
Grazie per l'esempio allegato, purtroppo l'ho aperto con B4A e mi dà un sacco di errori. Forse dovrei fare riferimento a qualche libreria?
 

pixet

Member
Licensed User
Longtime User
sorry,
tra il caldo, lo stress e la voglia di andare in vacanza l'ho fatto con B4J.
No problem lo rifaccio in B4X così potrai provarlo in varie piattaforme.
 

Sagenut

Expert
Licensed User
Longtime User
@Vasmar
Ti consiglio di installare anche B4J.
Molto comodo per fare tante prove generiche velocemente.
E anche magari per sperimentare il cross platform.
 

pixet

Member
Licensed User
Longtime User
Eccomi,
in allegato il file per le piattaforme B4A, B4i, B4j
i files sono stati provati e funzionano perfettamente per le piattaforme indicate, sono da perfezionare nei controlli per prevenire possibili errori che possono
scaturire da situazioni non previste (io la chiamo normalizzazione dei dati).
 

Attachments

  • Project_test_formato_interi_decimali.zip
    18.9 KB · Views: 32
Top