Buongiorno, vorrei convertire un char array in double usando atof, ma in alcuni "casi" la conversione arrotonda male (sbaglia l'ultimo decimale). Poco male, nell'uso come coordinata GPS questo equivale a pochi cm, ma vorrei capire "perché"!
Esempio:
double LAT1;
char LAT1CHAR[10]; //il dato ha due cifre e sei decimali
String subSD;
String SDstring = "LAT1:43.945035;LNG1:43.945035;"; //parto da una stringa che contiene le coordinate
subSD= SDstring.substring(5,14); //estraggo la latitudine
subSD.toCharArray(LAT1CHAR, 10); //metto nel char array
LAT1=atof(LAT1CHAR); //converto
Il monitor seriale mi stampa:
subSD= 43.945035 //quindi estraggo bene dalla stringa
LAT1CHAR= 43.945035 // quindi converto bene in char array
LAT1= 43.945034 // e mi sbaglia il decimale!!
NOTA: ho provato altri numeri a caso e a volte lo fa e a volt no, converte bene... ma non sono riuscito a capire quando.
... mah ... quello che forse non ti è chiaro è che sulle MCU AVR che montano i vari Arduino, i double NON esistono e tutto è trattato come normali float (32 bit) per cui, come chiaramente riportato nel reference:
Floats have 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.
Quindi ... non ti aspettare chissà quale precisione e dimentica di fare calcoli "seri" con le coordinate GPS per i quali ... occorrono dei veri duouble (64 bit).
Guglielmo
P.S.: ... e se cerchi, l'utente astrobeed, ne ha più volte ampiamente parlato qui sul forum :
E' vero ma qui non ci sono calcoli in mezzo.
Si parte dalla stringa subSD= 43.945035
Che poi viene convertita in un char array LAT1CHAR= 43.945035
Al momento di convertirlo in float scatta, forse, un arrotondamento?
Perchè ottiene LAT1= 43.945034?
lcursi
ti capita sempre oppure a seconda del valore dell'ultimo decimale?
Perché, come riportato, le cifre significative sono SOLO 6, massimo, in alcuni casi 7... e quel numero ne ha già 8 !!! In quelle condizioni NON è determinato cosa contengono le cifre successive ... :
zoomx:
E' vero ma qui non ci sono calcoli in mezzo.
Si parte dalla stringa subSD= 43.945035
Che poi viene convertita in un char array LAT1CHAR= 43.945035
Al momento di convertirlo in float scatta, forse, un arrotondamento?
Perchè ottiene LAT1= 43.945034?
lcursi
ti capita sempre oppure a seconda del valore dell'ultimo decimale?
varia a seconda del numero, ma non dell'ultimo decimale e basta. Nel senso che a volte funziona correttamente, a volte no, e facendo vari test non sono riuscito a trovare una regola
Se, come ha scritto Guglielmo, le cifre significative possono essere solo 6 mi sa che dovrai adattarti, la regola è che dopo le prime 6 cifre le altre possono essere diverse.
Dovresti cambiare MCU, specialmente se ci vuoi fare calcoli sopra.
zoomx:
Se, come ha scritto Guglielmo, le cifre significative possono essere solo 6 mi sa che dovrai adattarti, la regola è che dopo le prime 6 cifre le altre possono essere diverse.
Dovresti cambiare MCU, specialmente se ci vuoi fare calcoli sopra.
all'atto pratico, nell'uso come coordinata GPS, si passa da "sapere in che punto sei in una stanza" a "sapere in che stanza sei", quindi alla fine compatibile con la precisione che una antenna GPS di basso costo può dare.
lcursi:
all'atto pratico, nell'uso come coordinata GPS, si passa da "sapere in che punto sei in una stanza" a "sapere in che stanza sei" ...
... magari diciamo in "che appartamento" sei ... e se poi provi a fare in questo modo calcoli sulla distanza tra due punti ... l'errore è piuttosto notevole !
Guglielmo
P.S.: ricordatevi che i float sono rappresentanti secondo lo standard IEEE single precision con un bit per il segno, 8 bit per l'esponente e 23 bit per la parte decimale.
naaaaa che pessimismo!
Ad esempio fra 43.681781° - 10.710182°
e
43.681785° - 10.710187°
dove quindi le cifre sono cambiate entrambe e più di qualche punto, la distanza è 70 cm circa
se cambio un po' anche la penultima cifra, tipo:
43.681795° - 10.710197°
la distanza è 2 m circa.
Considerando che la precisione di un segnale è di qualche metro.. ci si può stare, no?
lcursi:
naaaaa che pessimismo!
Ad esempio fra 43.681781° - 10.710182°
e
43.681785° - 10.710187°
dove quindi le cifre sono cambiate entrambe e più di qualche punto, la distanza è 70 cm circa
Sicuro ?
Prova a fare il calcolo con ARDUINO della vera distanza tra due punti (Long1,Lat1, Long2, Lat2) e non tu con la calcolatrice ... con tutti gli arrotondamenti del caso che usa per ogni operazione con i float e fammi sapere
Esempio ... usa una formula che da una buona approssimazione:
p1 = (minlon, minlat) //longitudine e latitudine in radianti
p2 = (maxlon, maxlat) //longitudine e latitudine in radianti
dist = arccos( sin(minlat) * sin(maxlat) + cos(minlat) * cos(maxlat) * cos(maxlon – minlon) ) * 6371
(6371 è il raggio della Terra in Km; dist è espressa in Km).
Guglielmo
P.S.: Per una completa trattazione si può andare QUI
beh si! ho fatto una misura con il righello di Google Earth, poi anche su un sito che fa il calcolo on line boulter.com/gps/distance
nel primo caso 0m, nel secondo approssima a 1m
facciamo anche un esempio sui 100m di distanza (rispetto al punto di prima), scelgo: 43.682355° 10.711171°
questo punto è per google earth a 101m circa
per il sito di cui sopra : 0,1km (direi che ci siamo)
se cambio la PENULTIMA cifra decimale 43.682395° - 10.711121°
per Googole si fa a 101,87
per il sito resta 0,1km (precisione scarsina però)
allora provo Excel e la formula 6372,795477598* ARCCOS((SEN(B5) * SEN(C5) + COS(B5) * COS(C5) * COS(B6-C6)))
B5 e C5 partenza e B6 C6 arrivo
in questo caso le distanze sono
101,97 m nel primo caso
101,80 nel secondo
dire che si parla di posizine dei mobili dentro una stanza
SukkoPera:
Non hai capito: devi fare il calcolo su Arduino, non su Excel, che ha una precisione molto maggiore nei calcoli in virgola mobile.
obiettivo era valutare l'impatto teorico dell'errore dovuto alla conversione "atof" errata, ovvero: quanto conta in teoria l'ultima cifra? direi poco, visto che la penultima fa variare di 1-2 m circa
non mi pare che nell'altro post si parli della conversione atof (che è prima ed indipendente dal calcolo della distanza)
semmai se ne parla qui: string -> double con sei cifre decimali - #12 by lcursi - Software - Arduino Forum
nella quale mi si diceva "Quindi usa la atof() e quindi nessun arrotondamento" e siccome invece arrotonda, ho chiesto, anche per capire se sbagliavo io...
lcursi:
obiettivo era valutare l'impatto teorico dell'errore dovuto alla conversione "atof" errata, ovvero: quanto conta in teoria l'ultima cifra? direi poco, visto che la penultima fa variare di 1-2 m circa
... se non devi fare alcun calcolo, la cosa era già chiarita, il problema è se uno deve/vuole fare i calcoli su Arduino ... è li che casca l'asino !!!
gpb01:
... se non devi fare alcun calcolo, la cosa era già chiarita, il problema è se uno deve/vuole fare i calcoli su Arduino ... è li che casca l'asino !!!
Guglielmo
il calcolo lo farò con la funzione presente nella libreria TinyGPS, come abbiamo scritto. E poi validerò il tutto sul campo:)