"estrarre" il punto decimale da un float, come fare?

se gli serve sapere dov'è la la virgola basta fare (senta tirare in ballo le stringhe, per favore!)

copiaFloat = numeroFloat;
int a = copiaFloat;
int numeroDecimali=0;
while (a < copiaFloat){
    copiaFloat %= 10;
    numeroDecimali++;
}
int numeroInteri=0;
while (a > 0){
    a %= 10;
    numeroInteri++;
}

@ lesto
@ brunialti

ho provato ad usare lo sketc ma non compila =(

beh il mio non è uno sketch, ma un pezzo di codice.
Fino a quando uwe non manda la ricetta per la UWEbox© mi sa che devi postare il codice finale che hai usato e gli errori di compilazione.

lesto:
Fino a quando uwe non manda la ricetta per la UWEbox©

Se vuoi ti vendo una AstroBox(tm) per solo 9999 Euro, un vero affare :grin:

copiaFloat = numeroFloat;
int a = copiaFloat;

come fa a copiare su una variabile dichiarata int un float? dovrebbe trasformare in intero prima la variab float no?

copiaFloat %= 10; %= questo è un operatore binario mescolato a int e float ... qualcosa non va :slight_smile:

come fa a copiare su una variabile dichiarata int un float? dovrebbe trasformare in intero prima la variab float no?

l'autocast si occupa di tutto. al massimo deve forzarlo facendo

int a = (int)numeroFloat;

%= questo è un operatore binario

assolutamente no! questo è un operatore MATEMATICO, che vuol dire "il resto della divisione".
che però ora che ci penso non è stato implementato per i float...

quindi devi includere la math.h

copiaFloat = fmod(copiaFloat , 10);

se prima è servito castare a forza in int, servirebbe anche quì:

copiaFloat = (float)fmod(copiaFloat , 10);

se non fosse che float e doube son la stessa cosa

da Arduino - Home

copiaFloat %= 10;

sarà come dici tu

sketch_oct11b:8: error: invalid operands of types 'float' and 'int' to binary 'operator%'
sketch_oct11b:8: error: in evaluation of 'operator%=(float, int)'

pablos:
copiaFloat %= 10;

L'operatore modulo, %, si può usare solo con i numeri interi, non è ammesso l'uso con i float.

pablos:
copiaFloat %= 10;

sarà come dici tu

sketch_oct11b:8: error: invalid operands of types 'float' and 'int' to binary 'operator%'
sketch_oct11b:8: error: in evaluation of 'operator%=(float, int)'

L'operatore modulo, %, si può usare solo con i numeri interi, non è ammesso l'uso con i float.

ma il mio ultimo post conteneva già la soluzione (magari vi siete persi l'edit, mi son ricordato dopo che arduino IDE ha questa mancanza) su gcc, e tutti i linguaggi che possiedono nativamente l'operatore modulo non ho mai trovato questo comportamento

che però ora che ci penso non è stato implementato per i float...

quindi devi includere la math.h

copiaFloat = fmod(copiaFloat , 10);

se prima è servito castare a forza in int, servirebbe anche quì:

copiaFloat = (float)fmod(copiaFloat , 10);

se non fosse che float e doube son la stessa cosa

da Arduino - Home

lesto:
mi son ricordato dopo che arduino IDE ha questa mancanza) su gcc, e tutti i linguaggi che possiedono nativamente l'operatore modulo non ho mai trovato questo comportamento

Il compilatore di Arduino è il GCC, non c'entra nulla con l'IDE e le librerie di Arduino, l'operatore % è gestito dal GCC e l'errore lo da proprio il GCC, non mi obbligare a fare copia e incolla di pagine e pagine di manuali C dove si dice chiaramente che l'operatore % è esclusivamente per gli INTERI.
Se non ci credi guarda che errore mi da il C30 di Microchip, che si basa sul GCC, per una operazione % con i float:

// pezzo di codice incriminato
float pippo;
int pluto;

int main (void)
{
 pluto = pippo%10;	
	
//errore del compilatore
src\main.c: In function 'main':
src\main.c:132: error: invalid operands to binary %
Halting build on first failure as requested.

ok, ero convinto che il c ansi lo supportasse anche per float e double.

Comunque per tagliare la testa al toro il gioco del contare i numeri dopo la virgola si può fare anche senza usare il modulo usando una moltiplicazione per 10 finchè il numero moltiplicato (e diviso per 10^numero cifre contate) non è uguale alla forzatura del numero int

sto provando questo sketc a volte funziona a volte no
e piu precisamente sembra che ha la tendenza ad arrotondare la cifra immessa

MA CHI GLIELO HA ORDINATO IL MEDICO!!!!!!!!!!!!! ]:smiley:

ES: il valore 577.777 allinizio la prende (secondo il serial print 577.78)
e poi diventa 577.77696 =(

esempio se metto
valore_reale = 444.444;

tutto fila liscio il serial print da punto sulla 4 cifra (partendo da destra) e valore da inviare 444444 corretto,

l'idea di questo sketct è quello di prendere il numero
come int e float
sottrare float da int se da diverso da zero moltiplico per 10 e un contatore che e a 1 aumeta di un unita (posizione punto decimale)

se c'è un sistema per non fare arrotondare il float siamo sulla buona strada

unsigned long mela;

float pesca;
float valore_reale;
byte posizione_punto_sulla_cifra =1;
float k=0;
unsigned long p;

void setup() {
Serial.begin(9600);

valore_reale = 444.444; //cifre massime 7
//if (valore_reale > 1 && valore_reale <10) valore_reale = valore_reale * 1000000;

pesca = valore_reale; //cifre massime 7

}

void loop()
{
mela= pesca;

if (pesca-mela>0) posizione_punto_sulla_cifra = posizione_punto_sulla_cifra + 1, pesca = pesca*10;

Serial.print("posizione_punto_sulla_cifra ");
Serial.println(posizione_punto_sulla_cifra);

Serial.print("valore_reale ");

Serial.println(valore_reale, (posizione_punto_sulla_cifra-1) );

if(posizione_punto_sulla_cifra == 1) p= 1;
if(posizione_punto_sulla_cifra == 2) p= 10;
if(posizione_punto_sulla_cifra == 3) p= 100;
if(posizione_punto_sulla_cifra == 4) p= 1000;
if(posizione_punto_sulla_cifra == 5) p= 10000;
if(posizione_punto_sulla_cifra == 6) p= 100000;
if(posizione_punto_sulla_cifra == 7) p= 1000000;

//if (valore_reale > 999999) posizione_punto_sulla_cifra =posizione_punto_sulla_cifra-1;
//if (valore_reale > 999999) valore_reale =valore_reale/10;
Serial.print("valore da mandare al display ");
Serial.println(valore_reale*p,0 );

}


Io non sono un genio in programmazione devo spesso documentarmi per fare cose un po' più complesse, e molte volte non mi escono come vorrei, però quando posto un pezzetto di sketch è assicurato al 100% che l'ho provato prima sul mio arduino. Diversamente farei perdere tempo a chi già sta diventando scemo per capire come fare.
In conclusione se provaste ciò che suggerite in 2 post sarebbe chiuso il caso XD

lesto:
ok, ero convinto che il c ansi lo supportasse anche per float e double.

Vale anche per il C++ perché % è un operatore vero e proprio del C, cioè fa parte del linguaggio, per i float si usa fmod() che è una funzione di libreria.

pablos:
In conclusione se provaste ciò che suggerite in 2 post sarebbe chiuso il caso XD

+1 :slight_smile:
Sagge parole, prima di postare del codice tocca sempre provarlo, o almeno avvisare che non è testato, altrimenti si fa solo perdere tempo alla gente.

pablos:
Io non sono un genio in programmazione devo spesso documentarmi per fare cose un po' più complesse, e molte volte non mi escono come vorrei, però quando posto un pezzetto di sketch è assicurato al 100% che l'ho provato prima sul mio arduino. Diversamente farei perdere tempo a chi già sta diventando scemo per capire come fare.
In conclusione se provaste ciò che suggerite in 2 post sarebbe chiuso il caso XD

se no fossi al lavoro.... io ho dato la logica e gli strumenti, che ce lo mettano loro il compilatore. xD

@gingardu: credo che il problema con cui ti scontri è il fatto che i float, per come vengono memorizzati, possiedono un errore. Non puoi farci niente, se vuoi usare i float. per maggiori info: IEEE 754 - Wikipedia

gingardu:
sto provando questo sketc a volte funziona a volte no
e piu precisamente sembra che ha la tendenza ad arrotondare la cifra immessa

Ed ecco il classico caso di chi fa le domande e non legge tutte le risposte, ti ho avvisato molti post dietro che i float sono una rappresentazione esponenziale e che ti puoi scordare dei valori precisi, sono sempre leggermente diversi dal reale valore, calcolato con molta più risoluzione, per via degli arrotondamenti durante i calcoli e il particolare formato di rappresentazione.

Scusa gingardu però è difficile capire cosa vuoi fare, nel primo post chiedi di sapere in che posizione numerica si trova la virgola, quindi di conoscere i valori prima della virgola e dopo non ti interessa come scrivi qui:

cifra1=0 // non ha il punto decimale
cifra2=0 // non ha il punto decimale
cifra3=1 // HA il punto decimale
cifra4=0 // non ha il punto decimale
cifra5=0 // non ha il punto decimale
cifra6=0 // non ha il punto decimale

quindi qualcuno non approva a convertire il valore in string, però se ti serve sapere la posizione perchè non farlo?

Se poi tu dicessi in sintesi perchè vuoi questo valore, da dove arriva questo numero float, cosa devi fare una volta trovato questo valore ti si può suggerire un altra soluzione, ti ho chiesto in un post precedente che hai ignorato perchè questa insolita domanda sulla posizione della virgola.... te lo faccio io lo sketch dimmi cosa vuoi fare :slight_smile:

ciao

se è solo la posizione che ti serve

String stringa = "6546456456457.56720";
byte x; byte c; byte par;
char charBuf[30];

void setup()
{
  Serial.begin(9600);
 
  stringa.toCharArray(charBuf, 40);   
  char *p = charBuf;   
  while (*p != '\0') 
  {
    c++;
    if (*p == '.') { par=c; ++p; continue;}           
    ++p;
  }   	
 
 //----------------------------------debug-----------------------------------------------
   Serial.println("stringa esaminata " + stringa);
   Serial.println("il punto si trova alla posizione " + (String)(par) + " da sinistra");
   Serial.println("il punto si trova alla posizione " + (String)(c-par+1) + " da destra");   
   Serial.println("totale dei caratteri  " + (String)c);     
}

void loop(){}

pablos:
Scusa gingardu però è difficile capire cosa vuoi fare, nel primo post chiedi di sapere in che posizione numerica si trova la virgola, quindi di conoscere i valori prima della virgola e dopo non ti interessa come scrivi qui:

cifra1=0 // non ha il punto decimale
cifra2=0 // non ha il punto decimale
cifra3=1 // HA il punto decimale
cifra4=0 // non ha il punto decimale
cifra5=0 // non ha il punto decimale
cifra6=0 // non ha il punto decimale

quindi qualcuno non approva a convertire il valore in string, però se ti serve sapere la posizione perchè non farlo?

Se poi tu dicessi in sintesi perchè vuoi questo valore, da dove arriva questo numero float, questa insolita domanda sulla posizione della virgola.... te lo faccio io lo sketch dimmi cosa vuoi fare :slight_smile:

ciao

ovviamente le cose le chiedo perche ho intenzione poi di "usarle" voglio sapere dove si trova la virgola perche il tutto va "inviato" a 6 display 7 segmenti quindi teoricamente dovvrebbe esserre tutto semplice,
ma vedo che all'atto pratico non è cosi,
ora se la variabile assume un valore intero tra zero e 999999 il tutto viene visualizzato correttamente,
(il contenuto della variabile arriva da una lettura di un sensore, ma questo non vedo che importanza puo avere)

(metto xx per ricordare che il display ha 6 cifre)
se la variabile ha i decimali esempio xx99.99 deve succedere questo

mi deve portare a uno la cifra che ha il punto decimale e a zero quelle che non c'è l'hanno
attenzione queste variabili che sono che sono chiamate cifra1 cifra2 ...cifra 6 servono solo come "segnali,
potevo benissimo chiamarli mela1 mela2 mela3

cifra1=0 // non ha il punto decimale
cifra2=0 // non ha il punto decimale
cifra3=1 // HA il punto decimale
cifra4=0 // non ha il punto decimale
cifra5=0 // non ha il punto decimale
cifra6=0 // non ha il punto decimale

è in piu mi deve trasformare il numero con decimale in numero intero
in questo caso 99.99 va trasformato in 9999

altro esempio x123.66

cifra1=0 // non ha il punto decimale
cifra2=0 // non ha il punto decimale
cifra3= 0 // non ha il punto decimale
cifra4=1 // HA il punto decimale
cifra5=0 // non ha il punto decimale
cifra6=0 // non ha il punto decimale

in questo caso 123.66 va trasformato in 12366

da notare che
1.1 1.11 1.111 hanno il punto decimale su cifra diversa precisamente quinta quarta e terza,

invece 1.1 11.1 111.1 1111.1 11111.1 hanno il decimale tutti sulla stessa cifra guardando il display e precisamente la penultima contando da sinista (la quinta)