Italian trasformare un importo in un intero

LucaMs

Expert
Licensed User
Longtime User
B4X, meglio B4A perché sugli altri non posso giurarci, non ha funzioni di conversione a disposizione del programmatore.
Teoricamente, assegnando un valore ad una variabile di tipo X, questo viene automaticamente convertito in quel tipo (magari con troncamento, se da Float o Double alla gamma di interi).
Il punto è che, mi possono dire ciò che vogliono, qualcosa non va di sicuro, a prescindere da conversioni (casting) e precisione (Fload-Double); l'esempio lo dimostra nettamente (sia quello B4A in #4 che quello VB.Net in #17)
 

LucaMs

Expert
Licensed User
Longtime User
Non ho più Eclipse sul PC (o almeno credo :D); forse dovrei avere Android Studio (se non ho eliminato pure quello perché è pesante) ma forse potrei fare una prova usando Inline Java, per vedere se si ottiene lo stesso risultato sbagliato.
 

cimperia

Active Member
Licensed User
Longtime User
Non credo che ci sia un problema. O meglio, il problema è che nella vita reale, si tende a ignorare il fatto che 0.9999.... = 1, per davvero, anche se questo è molto sorprendente.

Ecco alcuni link interessanti:

Link1
Link2
 

cimperia

Active Member
Licensed User
Longtime User
Basic restituisce un valore che è stata regolata dalla funzione debug.write..., io penso.

Ci sono librerie Java che possono essere utilizzati quando la precisione è assolutamente necessaria (come quando hai a che fare con i soldi !!!)

Io non so se B4A implementa qualsiasi.
 

LucaMs

Expert
Licensed User
Longtime User
Basic restituisce un valore che è stata regolata dalla funzione debug.write..., io penso.
Sia in b4a che in VB.Net è possibile proseguire con altri calcoli basati sul valore restituito e vedrai che quello b4a risulterà sempre errato, a differenza di quello .Net.
Semmai il Log di b4a influisce, cosa che non dovrebbe fare.



Ci sono librerie Java che possono essere utilizzati quando la precisione è assolutamente necessaria (come quando hai a che fare con i soldi !!!)
Proprio questo è il punto: qui non si parla di precisioni astronomiche, ma di due semplici cifre decimali, per cui anche un Float dovrebbe essere sufficiente e non lo è.
 

cimperia

Active Member
Licensed User
Longtime User
Capisco la tua frustrazione, ma si deve accettare le limitazioni della lingua che uno codice con.

Ecco un link che mostra i valori java primiteve (byte, int ....) e un estratto viene copiato qui.

  • float: The float data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. As with the recommendations for byte and short, use a float (instead of double) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency. For that, you will need to use the java.math.BigDecimal class instead. Numbers and Strings covers BigDecimal and other useful classes provided by the Java platform.

  • double: The double data type is a double-precision 64-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. For decimal values, this data type is generally the default choice. As mentioned above, this data type should never be used for precise values, such as currency.
 

LucaMs

Expert
Licensed User
Longtime User
What they mean with "precise values, such as currency"?

Currency values need maximum 3 decimals! Almost always 2 decimals.

What can I do, then, with Float and Double? A nice picture? :D

Also, if so, I don't understand why Erel has not implemented those BigDecimal too.
 

udg

Expert
Licensed User
Longtime User
@LucaMs : nel tuo ultimo post ci vedo 3 quesiti:
1. Cosa intendono per "precise values"
2. A cosa servono Float e Double se "non sono precisi"
3. Perché non abbiamo in B4x un tipo BigDecimal

Per il primo punto, credo intendano dire che laddove hai la necessità di lavorare con valori assolutamente precisi, sia nella rappresentazione decimale che nella corrispondente binaria, allora devi usare i BigDecimal. In quel caso, 1250.60 decimale resta tale anche quando rappresentato in modo binario (ovviamente utilizzando più RAM e diventando più lento nelle operazioni). C'era qualcosa di simile anche in TurboPascal/Delphi.

Per il secondo punto, immagino che in determinati contesti avere un errore di 0.000000001 non sia importante.
Qui abbiamo che 1250.60 viene memorizzato (da java più che da B4x) come 1250.599999999. Se anche lo mettessimo in un loop per sommarsi a se stesso 1000 volte, il risultato (errato in aritmetica decimale) sarebbe ancora valido nella vita reale. Certo, un robot che dovesse operare una persona e posizionasse gli strumenti in modo errato non sarebbe rassicurante, ma anche la nostra invidiata meccanica di precisione non arriva a quel punto.

Per il terzo punto bisognerebbe sentire da Erel. Ma seguendo il link che avevo proposto si potrebbe scrivere qualcosa con la Reflection.
 

fabio_linate_milano

Member
Licensed User
Longtime User
salve a tutti

la cosa è resa ancora più insidiosa in quanto si verifica per un insieme di valori che è difficile da classificare.
Questo è l'esempio Java che ho fatto girare con alcuni valori


upload_2015-10-5_19-12-39.png

da notare che con numeri più grandi la cosa non succede.
Il nodo è venuto al pettine, ma in un testing software anche abbastanza completo poteva non evidenziarsi subito (penso ad uno sviluppo commerciale dove il cliente telefona dicendo che in alcune transazione sparisce un centesimo di euro!!!!!!)
Qualche considerazione, non da super esperto ma comunque da uno che, in passato, di sviluppo software ne ha masticato parecchio.
In primo luogo mi schiero dalla parte di chi considera questa cosa un bug. Poi. La cosa dipende da Java (B4A non c'entra niente) ma il fatto che il problema nasca dal substrato rende la cosa ancora + grave.
La cosa non dipende dall'hardware altrimenti non si spiegherebbero le prove in vb.net fatte da LucaMs (sarebbe interessante vedere cosa succede ad esempio sotto Linux, io ho una macchina con su Ubuntu, se ho tempo provo io)
I "workaround" sicuramente ci sono. Uno potrebbe essere quello di usare anche solo dei float (invece di double), l'altro quello che suggerisce moster67 in #11 (la funzione più adatta sarebbe la round2 nel mio caso).
Usare librerie, non so, prima vanno provate bene se non si conoscono a fondo.
Io quindi dovrei riuscire a portarmi avanti; ma comunque, ripeto, il tutto mi lascia un po' sbigottito.
Per le considerazione di udg certo è vero è un problema aperto, molti "teorici" disquisiscono molto su questa cosa.
(appena ho un po' di tempo consulterò la documentazione che proponi)
Il nostro PC è una "macchina a stati finiti" e non potremo mai rappresentare, ad esempio, un numero periodico o irrazionale.
Ma qui stiamo parlando 1250.6 * 100 !!!!!!!!!!!!!!!!!!

un saluto
 

LucaMs

Expert
Licensed User
Longtime User
@LucaMs : nel tuo ultimo post ci vedo 3 quesiti:
1. Cosa intendono per "precise values"
2. A cosa servono Float e Double se "non sono precisi"
3. Perché non abbiamo in B4x un tipo BigDecimal

Per il primo punto, credo intendano dire che laddove hai la necessità di lavorare con valori assolutamente precisi, sia nella rappresentazione decimale che nella corrispondente binaria, allora devi usare i BigDecimal. In quel caso, 1250.60 decimale resta tale anche quando rappresentato in modo binario (ovviamente utilizzando più RAM e diventando più lento nelle operazioni). C'era qualcosa di simile anche in TurboPascal/Delphi.

Per il secondo punto, immagino che in determinati contesti avere un errore di 0.000000001 non sia importante.
Qui abbiamo che 1250.60 viene memorizzato (da java più che da B4x) come 1250.599999999. Se anche lo mettessimo in un loop per sommarsi a se stesso 1000 volte, il risultato (errato in aritmetica decimale) sarebbe ancora valido nella vita reale. Certo, un robot che dovesse operare una persona e posizionasse gli strumenti in modo errato non sarebbe rassicurante, ma anche la nostra invidiata meccanica di precisione non arriva a quel punto.

Per il terzo punto bisognerebbe sentire da Erel. Ma seguendo il link che avevo proposto si potrebbe scrivere qualcosa con la Reflection.

Innanzitutto, voglio sottolineare quanto sono rinco, ormai: ho risposto in inglese (seppur maccheronico) :p

So' de coccio (restando nella lingua inglese) ma io non vedo come tu possa giustificare il punto 1, @udg. A me sembra chiaro che se tu dovessi eseguire calcoli in cui la precisione fosse elevata, quindi tanti decimali, tu dovresti usare un tipo di variabile che ti consentisse questo (diciamo pure quel BigDecimal che io non conosco ma suppongo sia una cosa del genere). Ma qui parliamo di due miseri decimali!!! per i quali un Float sarebbe sufficiente. Io insisto nel dire che non si tratta di scelta del tipo di variabile, ma di errore (Java, probabilmente) PERCHE' UN PROBLEMA DEL GENERE, IN .NET, NON ESISTE. E' chiaro che se io dovessi usare: 1.1234564789123456 avrei bisogno di più memoria e di un tipo di variabile adeguato, ma parliamo di due miseri decimali (l'ho già scritto? Beh, in questo caso non è demenza senile precoce, è voluto :p)


Per il secondo punto, immagino che in determinati contesti avere un errore di 0.000000001 non sia importante.
Qui abbiamo che 1250.60 viene memorizzato (da java più che da B4x) come 1250.599999999


Ma qui si parla di un errore di un centesimo, non di 0.00000000000000000000000000000001


Per il terzo punto, io suppongo che Erel considerasse, giustamente secondo me, sufficienti Double e Float. Ora non ricordo, ma il Double dovrebbe avere una precisione di almeno 6 decimali; ecco perché quel risultato non ha senso.

Ed infatti, ripeto, VB.Net non ha quei problemi. (per curiosità, andrò anche a vedere quali altri tipi di variabili decimali esistano in VB.Net)
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Il nostro PC è una "macchina a stati finiti" e non potremo mai rappresentare, ad esempio, un numero periodico o irrazionale.
Ma qui stiamo parlando 1250.6 * 100 !!!!!!!!!!!!!!!!!!

Appunto! Esattamente questo è il problema; sembra quasi che 0.6 non si possa memorizzare semplicemente così, anche se in binario.

Poi, il test di Fabio è... boh, non trovo nemmeno l'aggettivo giusto! Incredibile, pazzesco, allucinante... sarebbero aggettivi... "infinitesimali" :p


[tanto per sapere: che ambiente è quello dell'immagine, Fabio?
Va beh, tanto per continuare ad andare fuori tema... troppo fico il tuo Androidino :)]
 

cimperia

Active Member
Licensed User
Longtime User
Non ho fatto chiaro, ma la questione è soprattutto un problema di visualizzazione e di formato:

Ecco un esempio che mostra la risposta corretta perché ho formattato l'output come volevo:

Alcune funzioni utilizzate per visualizzare un numero si applicano alcuni formati predefiniti.
upload_2015-10-5_18-54-25.png
 

Attachments

  • upload_2015-10-5_18-49-55.png
    upload_2015-10-5_18-49-55.png
    407.8 KB · Views: 280
  • upload_2015-10-5_18-50-18.png
    upload_2015-10-5_18-50-18.png
    98.5 KB · Views: 220

fabio_linate_milano

Member
Licensed User
Longtime User
ho appena letto il nuovo post di cimperia
scusa ma è diverso, è chiaro che formattando l'output la cosa si corregge!
ma rimane il fatto che dentro la locazione di memoria il valore viene rappresentato in un certo modo
 

LucaMs

Expert
Licensed User
Longtime User
[poi oltretutto @cimperia ci spiegherà di dove è... mi fa pensare a Carlo da Imperia, ma mi sembra che lui conosca meglio l'inglese che l'italiano ;)]

Quindi, @cimperia , secondo te è solo un problema di output, di formattazione, ma il valore è memorizzato in maniera corretta?
Ok, troveremo il modo di scoprirlo.
 

cimperia

Active Member
Licensed User
Longtime User
[poi oltretutto @cimperia ci spiegherà di dove è... mi fa pensare a Carlo da Imperia, ma mi sembra che lui conosca meglio l'inglese che l'italiano ;)]

Quindi, @cimperia , secondo te è solo un problema di output, di formattazione, ma il valore è memorizzato in maniera corretta?
Ok, troveremo il modo di scoprirlo.

Yes, my Italian is poor :confused:, but I understand it 100% - mi chiamo Claudio Imperiale :cool:

Yes, you are right, the issue is only the display, not the value stored in memory. Otherwise I wonder how one could ever use floats and doubles!!:D
 
Last edited:
Top