Go Down

Topic: arrotondare un valore (Read 2 times) previous topic - next topic

ilconteste

Hola,
ignoranza mia, scusate,
ho una variabile di tipo FLOAT (una temperatura letta da un sensore LM35) ed attualmente ha 2 decimali
vorrei che tale valore venga arrotondato ad un solo decimale ( devo poi fare altri calcoli, non mi serve per mandarla a video)
come posso fare?
grazie 1000
stefano

Martinix

prova a dare un occhio qui:

http://arduino.cc/forum/index.php?topic=75547.0;wap2
Le informazioni date, son suggerimenti, osservazioni, ma come le applicate è a vostro rischio e pericolo!

f.schiano

Dai un'occhiata anche qui:
http://www.arduino.cc/playground/Code/PrintFloats

Penso faccia proprio al caso tuo....

Qui c''e un'altra discussione che potrebbe interessarti in cui l'autore aveva il tuo stesso problema:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1278422972

Spero di esserti stato utile.

Ciao,
Fab.
L'impossibile...richiede solo piu' tempo!

ilconteste


prova a dare un occhio qui:

http://arduino.cc/forum/index.php?topic=75547.0;wap2


ehmmm vediamo se ho capito
esiste un qualcosa (una funzione ?) setprecision()
che nell'esempio viene utilizzato con lo streaming (che non conosco....)
come dovrebbe invece essere la sintassi nel formato "nativo" di arduino?

inoltre di che libreria ha bisogno? SdFat.h ?

quindi se io ho
float variabile =20.1645
con tale funzione potrei arrivare ad avere un risultato di 20.2 ( arrotondato ad 1 decimale)
con un qualcosa del tipo risultato= setprecision(variabile, 1) ??

grazie!!!


leo72


Hola,
ignoranza mia, scusate,
ho una variabile di tipo FLOAT (una temperatura letta da un sensore LM35) ed attualmente ha 2 decimali
vorrei che tale valore venga arrotondato ad un solo decimale ( devo poi fare altri calcoli, non mi serve per mandarla a video)
come posso fare?
grazie 1000
stefano

Ma in sostanza che devi farci? Internamente i float sono molto imprecisi, sulla seriale l'arrotondamento di default è a 2 cifre decimali ma in realtà dietro ci sono diverse altre cifre che non vengono visualizzate ma ci sono.

ilconteste



Ma in sostanza che devi farci? Internamente i float sono molto imprecisi, sulla seriale l'arrotondamento di default è a 2 cifre decimali ma in realtà dietro ci sono diverse altre cifre che non vengono visualizzate ma ci sono.


perchè dici che i float sono molto imprecisi? cosa significa? cosa dovrei usare?
infatti non è un problema di serale o lcd.

leggo diverse temperature, interne, esterne, mandata e ritorno caldaia e comando delle valvole miscelatrici in base a dei calcoli (niente di scientifico, semplici moltiplicazioni - sottrazioni etc) ed alla curva climatica ( una tabella), partendo appunto dalle temperature rilevate.
dopo i "miei" calcoli mi troverò dei valori con diversi decimali ma che poi dovrò arrotondare ad 1 decimale o forse anche alla mezza unità (0.5)

tnks!!!




astrobeed


ho una variabile di tipo FLOAT (una temperatura letta da un sensore LM35) ed attualmente ha 2 decimali


Il float non ha due decimali, ne ha fino a 6 a seconda del numero di cifre prima della virgola, i due decimali sono quelli che ti fa vedere di default la print, come ti ha già detto Leo.
Il sensore LM35 ha una precisione di 0.5°, assolutamente inutile trattarlo con un float, usa solo valori interi eventualmente rapportandoli tra loro con moltiplicazioni per 10, 100, 1000, meglio ancora se lo fai in binario per potenze di due, e solo alla fine eventualmente visualizzi in formato decimale dividendo il numero per 10^n a seconda dei decimali desiderati e stampi la parte intera e quella decimale separate da un punto.
Esempio pratico, per LM35 ottieni direttamente la temperatura in centigradi dividendo per due i count del ADC (aRef = 5V), se l'ADC ritorna 40 count corrispondono a 20°, se tieni conto anche dei count dispari hai automaticamente anche i 0.5°, 41 count = 20.5° che diventa 205 (41*10/2 = 41*5) espresso come numero intero.

ilconteste



Il float non ha due decimali, ne ha fino a 6 a seconda del numero di cifre prima della virgola, i due decimali sono quelli che ti fa vedere di default la print, come ti ha già detto Leo.
Il sensore LM35 ha una precisione di 0.5°, assolutamente inutile trattarlo con un float, usa solo valori interi eventualmente rapportandoli tra loro con moltiplicazioni per 10, 100, 1000, meglio ancora se lo fai in binario per potenze di due, e solo alla fine eventualmente visualizzi in formato decimale dividendo il numero per 10^n a seconda dei decimali desiderati e stampi la parte intera e quella decimale separate da un punto.
Esempio pratico, per LM35 ottieni direttamente la temperatura in centigradi dividendo per due i count del ADC (aRef = 5V), se l'ADC ritorna 40 count corrispondono a 20°, se tieni conto anche dei count dispari hai automaticamente anche i 0.5°, 41 count = 20.5° che diventa 205 (41*10/2 = 41*5) espresso come numero intero.


dunque:
mannaggia a me che vi ho detto delle cose che vi stanno facendo confondere
diciamo che ho una variabile float con N decimali ( non so quanti sono).. come faccio ad arratondarla ad 1 solo?
(lascia stare che il dato proviene da un lm35 che cmq se si usa il riferimento interno 1V1 ha pure i decimi... e che ho detto che vedo solo 2 decimi)

astrobeed


diciamo che ho una variabile float con N decimali ( non so quanti sono).. come faccio ad arratondarla ad 1 solo?


E qui ritorniamo al discorso che ti ho fatto prima su i count dell'ADC che ti forniscono direttamente un valore alla prima cifra decimale con step di 0.5° come serve.

Quote

(lascia stare che il dato proviene da un lm35 che cmq se si usa il riferimento interno 1V1 ha pure i decimi... e che ho detto che vedo solo 2 decimi)


Cosa non ti è chiaro del fatto che gli LM35 hanno una precisione di 0.5° pertanto non ha alcun senso leggere i decimi di grado ?

ilconteste




E qui ritorniamo al discorso che ti ho fatto prima su i count dell'ADC che ti forniscono direttamente un valore alla prima cifra decimale con step di 0.5° come serve.



Cosa non ti è chiaro del fatto che gli LM35 hanno una precisione di 0.5° pertanto non ha alcun senso leggere i decimi di grado ?



lascia stare ADC , non ce l'ho più :) ho solo pure variabili
se faccio: (passami la forma)
7.2245/3.41=2.12 e voglio arrotondarlo (tutte le variabili sono float)??

scusa ma dal datasheet del lm35 dice che ha una accuratezza di +/- 0.5 non che legge "solo intervalli" di 0.5
i centesimi li hai eccome, ovvio il valore letto può essere sballato fino a +/- 0.5 gradi

astrobeed


se faccio: (passami la forma)
7.2245/3.41=2.12 e voglio arrotondarlo (tutte le variabili sono float)??


Non esiste l'arrotondamento in Arduino, se lo vuoi te lo devi scrivere e comunque 7.2245/3.41 fa 2.118621 come valore float e non 2.12

Quote

scusa ma dal datasheet del lm35 dice che ha una accuratezza di +/- 0.5 non che legge "solo intervalli" di 0.5
i centesimi li hai eccome, ovvio il valore letto può essere sballato fino a +/- 0.5 gradi


Ovvio che la tensione in uscita dal LM35 cambia in modo analogico, ma non ha alcun senso leggere le variazioni di 1 mV, o meno, visto che comunque non sono attendibili, come ti ho già spiegato leggi i count del ADC e ognuno corrisponde a 0.5°, più semplice di così è impossibile, poi se vuoi complicarti inutilmente la vita con i float sei liberissimo di farlo.

leo72

A parte la spiegazione tecnica di astro, voglio solo dirti 2 cose:

1) un float è impreciso per il semplice fatto che un numero in virgola mobile è una mantissa moltiplicata una base elevato ad un esponente.
Per capire un po' le cose leggi qui:
http://it.wikipedia.org/wiki/Numero_in_virgola_mobile
http://arduino.cc/en/Reference/Float
Capirai che una precisione ASSOLUTA non l'avrai mai, per i limiti stessi dati dalla quantità di informazioni memorizzabili in 4 byte, che è la dimensione di un float in Arduino. Cito ad esempio dal secondo link:
Quote
Floating point numbers are not exact, and may yield strange results when compared. For example 6.0 / 3.0 may not equal 2.0


2) una "sottospecie" di arrotondamento puoi averlo usando una moltiplicazione e una divisione per 10^(numero di cifre dopo lo zero). Ad esempio, questo codice arrotonda (o per lo meno cerca di farlo) un numero a 2 sole cifre decimali.
Code: [Select]
float numero, risultato;
  numero=i_tuoi_calcoli;
  risultato=(int(numero*100))/100; //100=10^2 per 2 cifre decimali


ilconteste

ok, grazie a d entrambi!

Go Up