float to int

salve

ce la possibilità di risolvere il problema della conversione da una variabile float a una int senza perdere la precisione di troncatura?

val int = (int)(val float * 100.0);

ad esempio un float di 16,50 convertito in int mi diventa 1649

grazie

Che range di valori devi trattare?
Quanti decimali ti servono?

fratt:
Che range di valori devi trattare?
Quanti decimali ti servono?

sono misurazioni di PH quindi da 0 a 14 con 2 decimali

esempio PH 7.55

>birrohgt: premesso che quello che hai scritto è sintatticamente scorretto, se provi questo:

void setup() {
   //
   int vInt = 0;
   float vFloat = 16.50;
   //
   delay(500);
   Serial.begin(115200);
   //
   vInt = vFloat * 100.0;
   Serial.print("Valore convertito = ");
   Serial.println(vInt);
}

void loop() {
   // put your main code here, to run repeatedly:

}

… vedi che stampa esattamente 1650 … quindi ? ? ?

Guglielmo

In ogni caso occorre ricordare poi come sono fatti i float (che su Arduino sono a 32 bit) e quanto viene ben specificato:

The float data type has only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point. Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float.

... inoltre, sempre relativamente alla precisione:

Floating point numbers are not exact, and may yield strange results when compared. For example 6.0 / 3.0 may not equal 2.0. You should instead check that the absolute value of the difference between the numbers is less than some small number.

Una interessante precisazione sulla loro precisione la fece poi a suo tempo Sulimarco ... leggere da QUI in poi ...

Guglielmo

birrohgt:
sono misurazioni di PH quindi da 0 a 14 con 2 decimali

esempio PH 7.55

In alternativa tratta tutto come intero, con le ultime 2 cifre che rappresentano sempre i decimali...
Ph 7.00 sarà 700
Ph 6.5 sarà 650

Meno risorse, meno rischi di arrotondamenti, ecc

fratt:
In alternativa tratta tutto come intero ...

... dipende se è lui a fare la conversione in float o se usa una qualche libreria che gli da già il valore float ... ::slight_smile:

Se semplicemente lui legge un analogico e fa le varie moltiplicazioni ... è banale, se usa una libreria ... ci dovrebbe mettere le mani dentro.

Guglielmo

uso una libreria (AnalogPHMeter.h) per la lettura del ph tramite un pin analogico di arduino che mi da la variabile float del valore del ph che poi devo convertire in int per inviarla con il protocollo modbus rs485 ad un altro arduino

se il float è 12.76

in int mi viene 1275

... e allora vedi mio post #3 e successivi.

Quella libreria lavora tutto con i float (e dubito che già essa, di per sé, dia valori esatti e non arrotondati ... visto tutte le operazioni che fa ::slight_smile:) e ... occorrerebbe riscriverla da capo.

Guglielmo

birrohgt:
ad esempio un float di 16,50 convertito in int mi diventa 1649

Come sai che il float è esattamente 16,50?
Potrebbe essere 16,495 e moltiplicando e troncando ottieni 1649.
Per curiosità prova a sommare 0,005 prima di convertire.

vi riporto il serial moniror con i valori alcuni sono convertiti bene altri no

sulla colonna di sinistra è il flot che mi fa la libreria (logicamente ora non è collegata la sonda ph e i valori sono casuali) a sinistra ci sono le rispettive conversioni a int facendo la moltiplicazione * 100 quelle sottolineate venno bene

15.83 1582
15.88 1587
15.80 1579
15.96 1595
15.96 1595
15.72 1571
15.72 1571
15.80 1579
15.88 1587
15.74 1574
15.74 1574
15.85 1585
15.96 1595
16.01 1601
15.91 1590
15.99 1598
16.01 1601
15.99 1598
15.72 1571
15.91 1590
15.93 1593
15.99 1598
15.88 1587

Curiosità... che forse non serve a niente... se moltiplichi per 1000 che valori ti da?

Curiosità 2... Per la tua applicazione è realmente necessaria una precisione al centesimo?

Hai letto la risposta di Claudi_FF (post #9) ? ... perché, sono quasi certo, quello è il problema ... che tu NON vedi tutto il numero float !

Prima di fare quello che dice Claudio_FF ... stampa i valori float in questo modo: "Serial.print(tuoValoreFloat, 4);" e vedrai i VERI valori con 4 cifre decimali.

Guglielmo

gpb01:
Hai letto la risposta di Claudi_FF (post #9) ? ... perché, sono quasi certo, quello è il problema ... che tu NON vedi tutto il numero float !

Prima di fare quello che dice Claudio_FF ... stampa i valori float in questo modo: "Serial.print(tuoValoreFloat, 4);" e vedrai i VERI valori con 4 cifre decimali.

Guglielmo

ho fatto come mi hai suggerito la cosa è strana ora me li fa tutti bene inserendo il Serialprint (x ,4) strano se tolgo il 4 li sbaglia

15.8790 1587
16.2289 1622
15.9598 1595
15.8790 1587
16.2289 1622
15.9059 1590
16.0405 1604
16.1212 1612
15.9598 1595
16.2289 1622
15.9328 1593
16.2558 1625
15.8521 1585
16.2020 1620
15.8790 1587
16.2289 1622
15.9059 1590
16.2289 1622
15.8790 1587
16.2558 1625
15.8521 1585
16.2558 1625

fratt:
Curiosità... che forse non serve a niente... se moltiplichi per 1000 che valori ti da?

Curiosità 2... Per la tua applicazione è realmente necessaria una precisione al centesimo?

no è solo motivo di studio ma potrebbe andare bene ugualmente

ma non hai provato con gli "stessi" numeri

prova a stampare due volte, prima a 2 e a poi a 3 decimali il float e stampare l'int convertito

credo che avrai sorprese...........

Standardoil:
ma non hai provato con gli "stessi" numeri

prova a stampare due volte, prima a 2 e a poi a 3 decimali il float e stampare l'int convertito

credo che avrai sorprese...........

se stampo sul monito seriale il float con 3 o 4 decimali la conversione viene perfetta
invece con 2 decimali li sbaglia

ma perche?

birrohgt:
ho fatto come mi hai suggerito la cosa è strana ora me li fa tutti bene inserendo il Serialprint (x ,4)

... vedo che NON hai capito ... li faceva anche prima tutti bene ... ovvio che se tu stampi con solo DUE decimali è chiaro che il Serial.print() arrotonda a 2 decimali e quindi 15.8790 diventa 15.88 mentre se tu fai la moltiplicazione per 100.0 NON c'è l'arrotondamento e tu vedi, giustamente 15.87.

Le moltiplicazioni funzionavano TUTTE bene, eri tu che vedevi i numeri sbagliati perché arrotondati dalla Serial.print() che, di base, usa ed arrotonda a due decimali (basta andare a studiare il reference) !!!

Guglielmo

ah ok grazie mille :confused:

birrohgt:
se stampo sul monito seriale il float con 3 o 4 decimali la conversione viene perfetta
invece con 2 decimali li sbaglia

ma perche?

Io ho scritto stampare 2 e 3

Non 3 o 4

E significa assieme

O significa in alternativa

O non capisci o non vuoi capire

Ma io ho quindi altro da fare, anche in futuro, mi spiace

La domanda é anche se hai la precisione di misura e conversione per garantire il centesimo di pH.

Se usi il ADC del Arduino a 10 Bit e se (ne dubito) usa tutta l'escursione possibile per il valore pH da miisurare ( da 0 a 1023 ADC) la risoluzione é 14:1023 = 0,013. La risoluzione vuol dire il valore da una lettura a quella sucessiva.

Inoltre parlando della precisione ne dubito che il circuito di amplificazione abbia un errore sotto il 0,1% per garantire una lettura veritiera del centesiom di pH.

Ciao Uwe