Ich will ein float im EEPROM ablegen und auslesen. Klappt eigentlich
auch. Aber ich will feststellen, ob da schon ein Wert abgelegt wurde,
oder nicht (neuer Chip) und dann einen Standardwert nehmen. Das klappt
nicht. µC: ATmega32
Ich habe:
float epromwert EEPROM;
float wert=0;
...
eeprom_read_block(&wert, &epromwert, sizeof(float));
Wenn ich wert mit
dtostrf (wert, 6, 3, text);
konvertiere, bekomme ich bei einem leeren EEPROM (FF) "NAN". Ok, so weit
ja auch brauchbar. Jetzt dachte ich, ich prüfe mit
isnan (wert)
ob das Ergebnis aus dem EEPROM auslesen eine Zahl ist. Aber die Fkt.
liefert immer 0
:-(
Wie mache ich's denn richtig?
Hallo Florian,
eine interessante Fragestellung. Die beiden Funktionen in der avr-libc
(Version 1.4.4) haben eine unterschiedliche "Meinung" darüber was ein
NaN ist, ich denke, die richtige Definition müßte sich in IEEE-754
finden, bei Interesse danach 'googeln' oder auch mal bei
http://en.wikipedia.org/wiki/NaN vorbeischauen).
bei isnan() findet sich:
CPI r25, 0xFF ; NaN is 0xffc0XXXX
BRNE .Lfalse
CPI r24, 0xC0
BRNE .Lfalse
bei dstrtof():
cpi r17, 0xff ; NAN ?
brne 1f
Es ist nicht auszuschliessen, dass avr-libc das noch nicht 100 %-ig
implementiert (siehe auch
https://savannah.nongnu.org/bugs/?group=avr-libc&func=browse&set=open ,
hier Item # 13330), ich würde das daher in der gegenwärtigen Situation
'schmutzig' lösen und auf 0xffff (bzw. 2 Worte mit 0xffff) abprüfen.
Wenn (float)0xfffffffff eine gültige Float-Zahl ist, dann hat man
natürlich ein Problem... ich hab' gerade kein AVR-System hier, was käme
denn da raus ?
Ciao
Hermann-Josef
Ah. Dann kann man sich ja totsuchen. Nachzuschauen, wie die Funktionen
implementiert sind, käme mir nie in den Sinn. Ich gehe (blauäigig, wie
ich wohl zugeben muß) davon aus, daß die Dinge so funktionieren, wie sie
sollen.
Ich hatte es noch etwas dreckiger gemacht und in einen String gewandelt
und dann mit strcmp auf "NAN" geprüft.
Aber der Test auf FF geht auch (in meinem Fall).
for (i=0; i<=6; i+=2)
{
if (eeprom_read_word((uint16_t *)(&wert+i)) != 0xFFFF)
is_number = 1;
}
Was mich jetzt nur noch stutzig macht, ist das ein double lediglich 4
Bytes belegt, wie auch ein float.
Naja, davon abgesehen, dass das gesamte Handling der IEEE754-
Sonderfeatures (Inf, NaN, Denormals) in der bestehenden
Implementierung unterbelichtet ist, ist es aber auch recht
blauäugig anzunehmen, dass ein 0xffffffff automatisch eine
gültige NaN wäre. Den Test auf nicht programmierten EEPROM
solltest du also sinnvollerweise schon explizit gegen 0xffffffff
vornehmen.
@ Jörg Wunsch
Ich ging ja nicht davon aus, daß das NaN ist, aber die Funktion isnan
lieferte halt immer 0, das störte mich. Das die Implementierung nicht OK
ist, kann man ja nicht unbdeingt wissen finde ich.
@Matthias Weißer
Aha. Wieder was gelernt (und vermutlich dann wieder vergessen, wenn ich
es das nächste mal brauche :-( ) Ist halt doof, wenn man mehrere
Sprachen kennt und immer wieder wechselt und dann Wissen transferieren
will...
Danke.