Prodotto di float per 100 ...

Scusate ma sto impazzendo :( . Memorizzo un intero maggiore di 255 in due celle EEPROM con:

if (var > 99) {
  float decVal = var / 100.00;
  int a = (int)decVal;
  float f = (decVal - a);
  int b = f * 100;
Serial.println(decVal);
Serial.println(a);
Serial.println(f);
Serial.println(b);
  EEPROM.update(addr, a);
  addr++;
  EEPROM.update(addr, b);
}

se var == 128 ottengo in output

1.28 1 0.28 27

perchè il float 0.28 moltiplicato per 100 diventa 27?

EEPROM.put (addr, decVal);

È più semplice ;).

Urca ... grazie, non sapevo del put, me lo studierò. Mi rimane comunque sconosciuta la motivazione della conversione di cui sopra

int b = f * 100.00;

Victor795:

int b = f * 100.00;

No, così non fa differenza. E' un problema di approssimazione infinitesimale a monte, ma sono alquanto ignorante al riguardo. Ho trovato questa proposta:

 int b = round(f * 100.0);

che non ho ancora provato, che ne pensate?

GigiG: No, così non fa differenza. E' un problema di approssimazione infinitesimale a monte, ma sono alquanto ignorante al riguardo. Ho trovato questa proposta:

 int b = round(f * 100.0);

che non ho ancora provato, che ne pensate?

è un refuso :

float b = f * 100.00;

mi da 28

Victor795: è un refuso : mi da 28

Ok, anche a me. O meglio, da 28.00, di cui basta ricavare l'intero con (int) ... ;)

EDIT: anzi no, int c = (int)b mi da di nuovo 27 ... :roll_eyes:

  int a = *((int*)&decVal);
  float f = (decVal - a) * 100.0;
  int b = *((int*)&f);

da testare

Non credo funzioni. In quel modo vai a reinterpretare come int i bit che rappresentano il float. Solo che quest'ultimo utilizza la rappresentazione IEEE-754 (o come si chiama, diciamo mantissa + esponente), che è totalmente diversa da quella degli interi.

GigiG: perchè il float 0.28 moltiplicato per 100 diventa 27?

Sei incappato nel classico caso di errore da float dovuto alla sua rappresentazione, il valore è sotto forma di esponenziale cosa che rende possibile trattare valori enormi, oltre che con i decimali, però non è per niente preciso, sopratutto nei float a 32 bit dove hai solo 6-7 cifre per la rappresentazione del valore. In pratica il tuo numero in realtà non è 0.28, è qualcosa del tipo 0.279998, quando lo visualizzi con la print, con solo due cifre, viene arrotondato a 0.28, però quando fai la moltiplicazione diventa 27.998 e troncato a 27 quando diventa intero. Il modo per evitare il problema è non usare i float, lavora solo con gli interi, previa moltiplicazione per 10-100-1000 a seconda di quanti decimali vuoi, e fai la conversione in float solo per visualizzazione se realmente necessaria. Oltre a guadagnare in precisione guadagni anche in velocità nei calcoli, anche se usi un long int a 32 bit ci vuole meno tempo per fare i vari calcoli rispetto ad un float, quest'ultimi sei obbligato ad usarli solo per certi calcoli, p.e. le funzioni trigonometriche, che si aspettano valori float in ingresso e rendono dei float.

Grazie astrobeed per la spiegazione, proverò a limitare tutto in int. Nel frattempo ho provato con:

float decVal = var / 100.00;
int a = (int)decVal;
float f = (decVal - a);
int b = round(f * 100.0);

che sembra funzionare, è 'un caso' o il round potrebbe risolvere la questione?

EDIT: la fonte è questa.

@Sukkopera, hai perfettamente ragione, quel frammento di codice serviva per tutt'altra cosa, scusate.