Float in char numero minimo bit

Salve a tutti,

sono nuovo del forum e della programmazione in arduino.

Ho 3 numeri float x,y,z da convertire in un'unica stringa che vorrei sia quanto più piccola possibile in termini di numero di bit.

I tre float che voglio trasmettere saranno al massimo composti da 3 cifre intere e 1 decimale. Possono essere positivi o negativi.
Faccio un esempio:

x=150,1
y=-140,2
z=200,1

Vorrei ottenere una stringa del tipo:

150,1 -140,2 200,1

Attualmente sto facendo una cosa simile:

float x,y,z;
char tot[120];
char a[6];
char b[6];
char c[6];

dtostrf(x,2,1,a);
dtostrf(y,2,1,b);
dtostrf(z,2,1,c);
sprintf(str, "%s %s %s", a, b, c);

Diciamo che funziona ma non capisco bene come scegliere le dimensioni dei char che ora sono abbastanza scelte "a caso"

Grazie a chiunque mi riesca ad aiutare :smiley:

Buona sera,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del nostro regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie. :slight_smile:

fabpolli:
Buona sera,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del nostro regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione … possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO … Grazie. :slight_smile:

sorry, rimediato

Non vedo il problema
Un segno, tre cifre, una virgola, un decimale
Fanno 6 caratteri per numero
3 numeri a fare 18, 2 separatori e un terminatore di stringa fa 21

In base alla documentazione ufficiale del produttore il valore viene convertito in array di char con una lunghezza massima specificata nel secondo parametro (width) con un numero di decimali massimi specificati nel terzo parametro.
Ad esempio:

float toConv = 123.4567;
dtostrf(toConv ,7, 3, outstr);

Metterà nell'array outstr il seguente valore: 123.456, quindi sette caratteri di cui tre decimali pertando dovrai definire outstr come

char outstr[8];

Perché tu chiedi 7 caratteri in totale come output, ma te ne serve uno in più per il terminatore di stringa ( '\0' )
Altro esempio:

float toConv = 1.23456;
dtostrf(toConv ,7, 3,outstr);

Metterà nell'array outstr il seguente valore: 1.234, sempre sette caratteri ma due spazi iniziali, e il vettore dovrà essere comunque definito di 8 caratteri (almeno).
Mettendo il secondo parametro negativo (-7 quindi) avresti il medesimo risultato nel primo caso, mentre nel secondo gli spazi sarebbero posti alla fine in quanto la lunghezza massima negativa specifica l'allineamento a sinistra

Concludendo se tu hai come valore massimo 999,9 e -999,9 la lunghezza massima dovrà essere 6 e il vettore inizializzato ad almeno sette caratteri perché meno e virgola occupano un carattere ciascuno.

Grazie a tutti per le risposte.

Sono arrivato al punto di aver tolto da mezzo i dtostrf in quanto passaggio inutile e sto utilizzando direttamente sprintf in questo modo:

sprintf(a, "%.1f %.1f %.1f", x, y, z);

Sto poi misurando la lunghezza di a con int lun=strlen(a);

L'unica cosa che non mi torna è che ad esempio alla terna:

-0.3 -0.3 2.1

strlen(a) mi restituisce 13. Dovrebbero essere 3 segni (forse 2?), 3 interi, 3 decimali, 3 virgole, 2 spazi, 1 terminatore per un totale di 15 (forse 14?).

L'unica idea che mi viene in mente è che forse sono 14 (il più non viene contato come simbolo?) e che strlen non conta il terminatore, è così?

Un minimo di ricerca ti avrebbe portato a questo sito che indica chiaramente che la strlen restituisce la lunghezza della stringa senza il terminatore, quindi segno intero punto decimale spazio segno intero punto decimale spazio intero punto decimale fa esattamente 13