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.
Hi beim AVRGCC ist sizeof(double) == sizeof(float) Double ist (im Prinzip) nur eine typedef auf ein float. Matthias
@ 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.
Laut Quellcode betrachtet die Funktion isnan() das Bitmuster 0xFFC0xxxx als NaN.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.