scusate, qualcuno mi può aiutare a trovare un metodo veloce per convertire un double in stringa?
Ho trovato procedure abbastanza articolate e vorrei essere sicuro che non esista qualcosa di pronto all'uso (magari mi sono perso in un bicchiere d'acqua)
Scusate ma ci sono alcune cose chje non mi tornano.
Per essere più precisi allego un codice di esempio nel quale a partire da un valore in stringa (Latitudine) lo converto in forma decimale
String Latitudine = "4528.947165";
void setup() {
Serial.begin(115200);
char gradi[2];
Latitudine.toCharArray(gradi,3);
double num_gradi =atoi(gradi);
char minuti_all[9];
Serial.print("Minuti come stringa: ");
Serial.println(Latitudine.substring(2,11));
Latitudine.substring(2,11).toCharArray(minuti_all,10);
double minuti = atof(minuti_all);
Serial.print("Minuti come double: ");
Serial.println(minuti);
//converto di nuovo da double a char
char temporaneo[9];
dtostrf(minuti,9,6,temporaneo);
Serial.print("Minuti come dtostrf: ");
Serial.println(temporaneo);
double lat_decimale=num_gradi+(minuti/60);
char Risultato[10] ;
dtostrf(lat_decimale,11,8,Risultato);
Serial.println(Risultato);
}
void loop() {
while(1);
}
la prima cosa strana è che se "riconverto" da double a char il valore dei minuti (+secondi) mi cambia ultima cifra
inoltre il risultato finale (Risultato) non riseco ad ottenerlo con 8 decimali (se non sbaglio in 32 bit ci stanno...)
La FPU dell'Atmega è capace di gestire nativamente solo numeri interi. I numeri in virgola mobile sono supportati via software. Per faar ciò viene usata la cosiddetta notazione con mantissa ed esponente. Le conversioni da e per float portano ad arrotondamenti. Inoltre la massima capacità di un float sull'Arduino è di 6/7 decimali, non di più http://arduino.cc/en/Reference/Float
leo, strano che nessuno ti abbia ancora bastonato. Il fatto che float e double siano rappresentati così non dipende dal fatto di avere una FPU o meno, anzi, la loro definizione arriva dallo standard IEEE 754.
Anche sui PC o sulle GPU C ansi compatibili (oltre che in java e mille altri linguaggi) i float sono rappresenteti così. occhio soprattuto a non confonderti con i FIXED PRECISION, dove puoi settare i numeri di decimali che vuoi avere.
In oltre dire che hai nove decimali di precisione non è vero: se il numero è una potenza di 2, allora hai precisione al 100% finchè non vai in overflow. Se non è multiplo di 2, potresti avere una grande perdita di precisione anche con numeri con pochi decimali.
graficamente ecco il discostamento dalla realtà di f(x) = log(1-x)/x:
A parte che non vedo il motivo per cui qualcuno debba bastonarmi, il fatto di avere una FPU capace di trattare e gestire numeri ed operazioni solo con interi era per far capire che hai dei sistemi di rappresentazione che possono introdurre delle imprecisioni nella conversione.
Sul fatto poi che la precisione sia a 6/7 decimali (non 9, non l'ho scritto) questo non me lo sono inventato io ma deriva proprio dallo standard IEEE754 che tu stesso hai citato. I float o double in Arduino sono in realtà dei numeri in virgola mobile a SINGOLA precisione perché sono "grandi" solo 32 bit, e per la loro natura hanno una precisione max di ~7 cifre:
Grazie a tutti per il supporto,
credo, a questo punto, che sia meglio trattare i double in php prima di caricarli su mysql...o almeno spero di avere più fortuna
veramente arriva a 8 BIT di ESPONENTE, e 23 per la parte decimale NORMALIZZATA, ma proprio per via dell'esponente che in realtà i numeri rappresentabili sono molto più ampi. E che si perde di precisione più ci allontana dai valori esponenziali.
per fare una prova salva 0,0000000000001 e vedrai che puoi (anche se il valore risultato subirà l'inevitabile errore)
Ma nessuno ha detto che non puoi salvare 0,00000000000ecccc1. Solo che poi in memoria non hai questo numero.
La precisione interna è quella, non si scappa. Se ti ricordi se ne discusse anche tempo fa.