Hallo, was passiert, wenn man folgenden Fall bei einem AVR (GCC/AVR-Studio) hat?
1 | uint16_t a = 0; |
2 | uint16_t b = 100; |
3 | |
4 | uint16_t c = b / a; |
Stürzt der Controller dann im Betrieb an dieser Stelle ab?
|
Forum: Mikrocontroller und Digitale Elektronik Was macht ein AVR bei einer Division durch Null?Hallo, was passiert, wenn man folgenden Fall bei einem AVR (GCC/AVR-Studio) hat?
Stürzt der Controller dann im Betrieb an dieser Stelle ab? Es entsteht ein schwarzes Loch welches ALLES einsaugt DER PROGRAMMIERER Ein Programmierer sprach einmal Im vollen Programmierungssaal (er sagt es lächelnden Gesichts): "Ich programmiere: Eins durch Nichts". Jedoch was soll ich weiter schreiben: Der Programmierer ließ es bleiben. in memoriam KLEN In C führt eine Division durch 0 zu einem Programm Abbruch. Ein Controller stellt dann wohl seine Arbeit ein bis zu einem Neustart. Du muss im Programm den Teiler selbst auf 0 prüfen und dann die gewünschten Massnahmen ergreifen.
Nobody schrieb: > In C führt eine Division durch 0 zu einem Programm Abbruch. Ein > Controller stellt dann wohl seine Arbeit ein bis zu einem Neustart. Wirklich??? Hätte gedacht, dass vielleicht ein Error-Flag gesetzt wird und das Programm ansonsten "normal" weitergeht... Ein AVR selbst kann gar nicht dividieren, da sein Befehlssatz keine Division kennt. Insofern ist alles, was passiert, abhängig von der Umsetzung des Hochsprachendivisionsbefehls in den letzlich ausgeführten Maschinencode. Nobody schrieb: > In C führt eine Division durch 0 zu einem Programm Abbruch. Ein > Controller stellt dann wohl seine Arbeit ein bis zu einem Neustart. Das kann man nicht so pauschal sagen. Das Ergebnis ist nicht definiert. Alles mögliche kann passieren, inklusive einem Prozessorhalt. Aber sehr wahrscheinlich ist das nicht. Gerade auf einem µC werden die Dinge meistens so gelagert, dass das Programm zumindest weiter läuft. Je nach Situation hat man dann ein einmalig falsches Zwischenergebnis (was immer noch fatal ist, nicht missverstehen), im nächsten Durchlauf durch die Hauptschleife sind dann aber die Zahlenwerte möglicherweise schon andere, so dass das Programm ab dann korrekt weiterlaufen kann. Gerade im Embedded-Bereich ist ein Prozessor-Halt der Super-Gau schlechthin. > Du muss im Programm den Teiler selbst auf 0 prüfen Das auf jeden Fall. Wenn durch 0 dividiert wird, dann deutet das sowieso meistens auf einen Sonderfall hin, der getrennt behandelt werden muss. :
Bearbeitet durch User
C definiert eine Division durch 0 als "undefiniert". Compiler und Runtime können also machen was sie wollen, morgen anders als heute. Wissenwollender schrieb: > Stürzt der Controller dann im Betrieb an dieser Stelle ab? Wie sollte er? Er hat keinerlei Absturzflags. Er zieht ganz profan von jedem Bit 0 ab, da es ohne Unterlauf geht. Das Ergebnis ist folglich 0b1111111111111111 bzw. 0xFFFF. Wenn Du einen Absturz willst, mußt Du ihn schon selber programmieren:
Häufig genug kriegt man - falls sich die Gleitkomma-Lib an die ANSI-Vorgaben hält - als Ergebnis eine NAN. Und das ist die größte Sch*** die es gibt, denn aus einer NAN kommt man anschließend durch nix mehr heraus. Also auch kein nachträgliches Abfangen im Programm mehr möglich. Hab ich selber schon oft genug erlebt und mich darüber schwarz ärgern müssen. W.S. W.S. schrieb: > Häufig genug kriegt man - falls sich die Gleitkomma-Lib an die > ANSI-Vorgaben hält - als Ergebnis eine NAN. Und das ist die größte > Sch*** die es gibt, denn aus einer NAN kommt man anschließend durch nix > mehr heraus. Was ein völlig korrektes Verhalten ist. Nicht nur gemäss ANSI, sondern auch gemäss einfacher Logik. Operationen auf undefinierte Werte können nur wiederum undefinierte Werte produzieren. Allerdings bezieht sich der Thread auf Integer-Rechnung, du aber auf Fliesskomma-Rechnung. :
Bearbeitet durch User
W.S. schrieb: > Häufig genug kriegt man - falls sich die Gleitkomma-Lib an die > ANSI-Vorgaben hält - als Ergebnis eine NAN. Und das ist die größte > Sch*** die es gibt, denn aus einer NAN kommt man anschließend durch nix > mehr heraus. Wie meinst du denn "kommt man nicht mehr heraus?". NAN ist doch nur ein spezieller Wert den eine Variable haben kann. Wieso muss man da irgendwo raus? Meist ist es doch auch so, einen Fehler wie Division durch Null will man nicht wirklich abfangen. Denn was kann man hier denn Bitte noch ausrichten? Das weist auf einen schweren Fehler in der Programmlogik hin, meist fehlende Überprüfung von Eingaben, oder schlimmer irgendwelche Schleifen die zu tief laufen. Also da ist ein sauberes stehenbeleiben die beste Lösung. Ein "Weiter so", wie im guten alten Basic mit dem Befehl "On Error Goto Next" behindert nur die Fehlersuche. Peter Dannegger schrieb: > Er zieht ganz profan von jedem Bit 0 ab, da es ohne Unterlauf geht. > Das Ergebnis ist folglich 0b1111111111111111 bzw. 0xFFFF. Der Controller schafft sich dann also in seinem Kosmos ein lokales Unendlich. cyblord ---- schrieb: > Meist ist es doch auch so, einen Fehler wie Division durch Null will man > nicht wirklich abfangen. Denn was kann man hier denn Bitte noch > ausrichten? Es gibt Funktionen, die gegen unendlich laufen. z.B., bei 'tan(90°)' muss es ja trotzdem weitergehen. Ralf G. schrieb: > cyblord ---- schrieb: >> Meist ist es doch auch so, einen Fehler wie Division durch Null will man >> nicht wirklich abfangen. Denn was kann man hier denn Bitte noch >> ausrichten? > > Es gibt Funktionen, die gegen unendlich laufen. z.B., bei 'tan(90°)' > muss es ja trotzdem weitergehen. Darum schrieb ich ja "meist". Warum soviele ironische Antworten? Die Frage ist absolut berechtigt. Zahlreiche Prozessoren kennen ein Exception-Handling, bei dem z.B. unterschiedliche Interrupts ausgelöst werden. Bei den x86 kompatiblen gibt es einen eigenen Interrupt für Division durch Null. Weiterhin gibt es dort einen Interrupt für unbekannte OPcodes. Dieser wurde zu 286 und 386SX Zeiten verwendet, um per Softwareemulator den 287/387er Koprozessor zu emulieren, der für die Fliesskommaberechnungen zuständig ist. Weiterhin gibt es Bibliotheken und Frameworks, die ähnliche Mechanismen bieten. Wie oben zurecht gesagt: > Insofern ist alles, was passiert, abhängig von der Umsetzung des > Hochsprachendivisionsbefehls in den letzlich ausgeführten Maschinencode. Es fehlt jedoch die Aussage, ob in bestimmten Toolchains solche Mechanismen eingebaut sind. Gerade als Anfänger in neuen Architekturen geht man von bekannten Mechanismen aus, und muss sich unterschiedliche Implementierungen und Herangehensweisen zunächst erarbeiten. Wissenwollender schrieb: > Der Controller schafft sich dann also in seinem Kosmos ein lokales > Unendlich. Das übliche Missverständnis. Unendlich ist als Ergebnis genauso richtig und falsch wie 65535 oder 42. Es kommt halt das raus, was der Algorithmus der Division erbringt, wenn man den Fall nicht eigens abfängt. Tipp des Tages schrieb: > Die Frage ist absolut berechtigt. Zahlreiche Prozessoren kennen ein > Exception-Handling, bei dem z.B. unterschiedliche Interrupts ausgelöst > werden. Nützt aber alles nix, weil hier nicht nach dem i.d.R. definierten Verhalten eines Prozessors gefragt wurde, sondern nach dem undefinierten (nicht: unspezifizierten!) Verhalten von Compiler bzw. dessen Rumtime. Tipp des Tages schrieb: > Zahlreiche Prozessoren kennen ein Exception-Handling Ein AVR hat sowas jedoch nicht. W.S. schrieb: > Häufig genug kriegt man - falls sich die Gleitkomma-Lib an die > ANSI-Vorgaben hält - als Ergebnis eine NAN. Nein. Man bekommt ein (vorzeichengerechtes) Inf, und das ist völlig korrekt: wenn man eine von Null verschiedene Zahl durch Null teilt, kommt nun einmal Unendlich dabei raus. (Dass sich die originale Frage jedoch auf Ganzzahlen bezog, wurde ja bereits erwähnt.) Für den simplen (compilezeit-konstanten) Fall wie in obigem Beispiel wird es sehr wahrscheinlich natürlich der Compiler schon bemerken. :
Bearbeitet durch Moderator
Jörg Wunsch schrieb: > Nein. Man bekommt ein (vorzeichengerechtes) Inf, und das ist völlig > korrekt: wenn man eine von Null verschiedene Zahl durch Null teilt, > kommt nun einmal Unendlich dabei raus. Man kann zwar das praktische Verhalten von Hardware oder Libs so definieren, mathematisch bleibt es jedoch undefiniert. https://de.wikipedia.org/wiki/Division_(Mathematik)#Ist_.C2.B9.E2.81.84.E2.82.80_.3D_.E2.88.9E.3F :
Bearbeitet durch User
A. K. schrieb: > Jörg Wunsch schrieb: >> Nein. Man bekommt ein (vorzeichengerechtes) Inf, und das ist völlig >> korrekt: wenn man eine von Null verschiedene Zahl durch Null teilt, >> kommt nun einmal Unendlich dabei raus. > > Man kann zwar das praktische Verhalten von Hardware oder Libs so > definieren, mathematisch bleibt es jedoch undefiniert. > Letzen Endes ist es aber in der Praxis auch ziemlich egal. Wenn bei einer Division die Möglichkeit besteht, durch 0 zu dividieren, dann muss dieser Fall gesondert behandelt werden. Und zwar bevor man dividiert. Erleichtert wird dieses dadurch, dass eine versuchte Division durch 0 sowieso meistens irgendeinen speziellen Sonderfall darstellt, den ich sowieso getrennt behandeln möchte. Und dann ist die vorlaufende Erkennung dieses Sonderfalls normalerweise bei weitem einfacher, als hinterher ein undefiniertes Divisionsergebnis zu erkennen und zu bearbeiten. :
Bearbeitet durch User
Karl Heinz schrieb: > als > hinterher ein undefiniertes Divisionsergebnis zu erkennen Undefiniert steht in der Compiler-Spezifikation, der Prozessor hat im konkreten Fall natürlich ein definiertes Ergebnis, wenn auch möglicherweise ein zufälliges. Es kommt aber nicht wirklich drauf an, ob man sich darauf versteift, dass das Ergebnis der Division undefiniert ist oder unendlich, weil man so oder so damit nicht weitermachen kann (der Prozessor kennt auch kein Unendlich). Genausowenig hilft die Darstellung NAN, die es bei real gibt, das bringt einen auch nicht weiter als eine Exception. Da ist ganz einfach der Programmierer gefragt, was geschehen soll. Georg Die Frage ist wirklich ernst gemeint: Läßt sich das ein "C"-Kompiler gefallen, wenn man ihm einen Quelltext gibt, der eine Division durch Null erzeugt? (Ich kann es nicht probieren, weil ich hier keinen derartigen Kram auf dem Rechner habe und ihn auch nicht installieren könnte bzw. dürfte) MfG Paul Paul Baumann schrieb: > Die Frage ist wirklich ernst gemeint: > Läßt sich das ein "C"-Kompiler gefallen, wenn man ihm einen Quelltext > gibt, der eine Division durch Null erzeugt? Was ein ordentlicher Compiler ist, wird im Zuge der Constant-Folding Optimierung drauf kommen, dass hier durch 0 dividiert wird und eine entsprechende Warnung rausgeben. Verpflichtet dazu ist er, wie bei allen Warnungen, allerdings nicht. Im C-Standard gibt es keine Warnungen. Im C Standard steht nur, was ein Error ist und was nicht. Warnungen sind freiwillige Serviceleistungen des Compilers. :
Bearbeitet durch User
Paul Baumann schrieb: > Läßt sich das ein "C"-Kompiler gefallen, wenn man ihm einen Quelltext > gibt, der eine Division durch Null erzeugt? GCC gibt eine Warnung. Wenn er es merkt. Paul Baumann schrieb: > Läßt sich das ein "C"-Kompiler gefallen Naja, nehmen wirs mal ernst: was verstehst du unter "gefallen lassen"? Wenn er es merkt übersetzt er das Programm nicht oder gibt wenigstens eine Warnung aus - das kann man einstellen, man hat also in der Hand, was er sich gefallen lässt. Es macht aber wenig Sinn, alle Fehler und Warnungen abzustellen, da kommt keine brauchbare Software raus. Georg Paul Baumann schrieb: > Die Frage ist wirklich ernst gemeint: > Läßt sich das ein "C"-Kompiler gefallen, wenn man ihm einen Quelltext > gibt, der eine Division durch Null erzeugt? Ja. Wenn er schlau ist, kann er vieleicht eine Warnung ausgeben, aber prinzipiel geht es ihn nix an, wenn du so etwas machst. Tipp des Tages schrieb: > Die Frage ist absolut berechtigt. Zahlreiche Prozessoren kennen ein > Exception-Handling, bei dem z.B. unterschiedliche Interrupts ausgelöst > werden. > Bei den x86 kompatiblen gibt es einen eigenen Interrupt für Division > durch Null. Diese Prozessoren können dividieren. Ein AVR aber kann das nicht. Verwechsle nicht Hochsprache mit den vom Prozessor ausgeführten Maschinenbefehlen - bei einem Prozessor, der keine Division kennt, ist eine Exception (oder ein Software-Interrupt) für einen Divisionsfehler ziemlich ... nutzlos. Georg schrieb: > Karl Heinz schrieb: >> als >> hinterher ein undefiniertes Divisionsergebnis zu erkennen > > Undefiniert steht in der Compiler-Spezifikation, der Prozessor hat im > konkreten Fall natürlich ein definiertes Ergebnis Frage nicht gelesen? Ein AVR hat keinen Divisionsbefehl. Eine Division, ganz egal ob Ganzzahl oder Fließkomma wird immer von einer Biblio- theksfunktion ausgeführt. Und deren Verhalten ist zwar sicher für eine spezifische Toolchain vorhersagbar, im Allgemeinen jedoch undefiniert. > wenn auch möglicherweise ein zufälliges. Das nun ganz sicher nicht. Computer funktionieren deterministisch. > Genausowenig hilft die > Darstellung NAN, die es bei real gibt, das bringt einen auch nicht > weiter als eine Exception. Der Punkt ist, daß C für Arithmetik keine Exceptions vorsieht. Weder für Division durch Null noch (was sehr nützlich wäre) für einen Überlauf. Und weil es keine out of band Signalisierung gibt, hat man die NaN Pseudowerte eingeführt, um wenigstens in band signaling zu haben. Weil man dafür aber den Wertebereich des Ergebnisses einschränken muß hat man es nur für Fließkommazahlen gemacht, weil es da ohnehin schon ungültige interne Darstellungen gibt, von denen man einfach ein paar passend umdefiniert hat. Langer Rede kurzer Sinn: das NaN Ergebnis ist die Exception. XL Danke für die Antworten auf meine Frage. Es stellt sich aber gleich noch eine: Wenn ich den Text von Axel richtig verstanden habe, dann gibt es auch da keine Fehlermeldung, wenn ich z.B. 2 Byte miteinander multipliziere und das Ergebnis aus Versehen oder Unachtsamkeit auch in eine Bytevariable hineinwürgen will? Wenn das so ist, will ich kein "C" haben. MfG Paul Axel Schwenke schrieb: > Das nun ganz sicher nicht. Computer funktionieren deterministisch. Wie würdest du denn den Inhalt nicht initialisierter Variablen bezeichnen? Klar arbeitet ein Prozessor deterministisch, aber für den Programmierer ist der Inhalt nicht vorhersehbar. Man kann ja auch behaupten, die Brownsche Molekularbewegung sei in Wirklichkeit deterministisch, bloss hilft das überhaupt nicht weiter. Georg Paul Baumann schrieb: > Wenn das so ist, will ich kein "C" haben. C ist eben nichts für Leute, die die Tante brauchen um Lulu zu gehen. Dein heiss geliebtes BASCOM hat auch so seine Probleme. Karl Heinz schimpfte: >C ist eben nichts für Leute, die die Tante brauchen um Lulu zu gehen. War Dir das Mittagessen zu heiß? >Dein heiss geliebtes BASCOM hat auch so seine Probleme. Das habe ich mit keinem Wort behauptet. Was hier los ist.... :-( Paul Irgendwie geht hier etwas durcheinander. Nämlich das Verhalten eines Atmel und "C". 1. Soweit mir bekannt juckt es einen AVR kein bisschen, wenn der durch Nix teilen soll. 2. Vor längerer Zeit habe ich mal eine 16-Bit Division aus den AVR- Bibliotheken extrahiert. Da war keine explizite Abfrage auf null. 3. NaN kenne ich nur im Zusammenhang mit Fließkommazahlen bzw. -bibliotheken. Darum ging’s hier aber nicht. Das Verhalten hier hängt wohl vom Compiler bzw. davon ab, ob man C oder C++ verwendet. Paul Baumann schrieb: >>Dein heiss geliebtes BASCOM hat auch so seine Probleme. > > Das habe ich mit keinem Wort behauptet. Was hier los ist.... Vielleicht kannst du dir vorstellen, das mit dieses dauernde C-Bashing mitlerweile schon ganz gehörig auf den Sack geht? Zumal viele derartige 'Untergriffe' immer wieder von Leuten kommen, die C überhaupt nicht ausreichend beherrschen um sich hier ein Urteil erlauben zu können. Ausserdem behauptet auch niemand, dass C das Beste seit geschnittenem Brot wäre. Alle C Programmierer sind sich bewusst, dass die Sprache ihre Problemkreise hat (die meistens dann auch gar nicht in den Bereichen angesiedelt sind, die immer wieder gerne von "C-Laien" kritisiert werden) Amateur schrieb: > 1. Soweit mir bekannt juckt es einen AVR kein bisschen, wenn der > durch Nix teilen soll. Es kann ihn ja auch nicht jucken. Er hat schlicht keinen Divisionsbefehl. Also wird er niemals dividieren. Die Division wird lediglich durch den Compiler nachgebildet, und genau darum dreht sich die Diskussion in letzter Zeit. Nicht um den AVR. Karl Heinz schrie: >Vielleicht kannst du dir vorstellen, das mit dieses dauernde C-Bashing >mitlerweile schon ganz gehörig auf den Sack geht? Ich habe mir nur erlaubt, 2 Fragen zu stellen -nicht mehr. >Zumal viele derartige >'Untergriffe' immer wieder von Leuten kommen, die C überhaupt nicht >ausreichend beherrschen um sich hier ein Urteil erlauben zu können. Ich beherrsche C nicht nur nicht ausreichend, sondern überhaupt nicht Das war auch der Grund für meine Fragen, die ich anderenfalls gar nicht hätte stellen müssen. Im Übrigen ist auch nicht die Pflicht eines Moderators, auf jeden Artikel zu antworten, dessen Inhalt nicht seinen Gefallen findet! Paul Paul Baumann schrieb: > Ich habe mir nur erlaubt, 2 Fragen zu stellen -nicht mehr. Nimms nicht persoenlich - Nein, du fragst nicht sachlich, sondern abwertend - das fiel auch mir auf. Du musst ja kein C nutzen, aber in einem Thread wie diesem ist irrelevant, was du von C haeltst... Paul Baumann schrieb: > Ich habe mir nur erlaubt, 2 Fragen zu stellen -nicht mehr. Nö, Paul: Paul Baumann schrieb: > Wenn das so ist, will ich kein "C" haben. Das war das, was Karl Heinz „auf die Palme“ gebracht hat und was er als „C-Bashing“ bezeichnet. Axel Schwenke schrieb: > Und weil es keine out of band Signalisierung gibt, hat man die NaN > Pseudowerte eingeführt, um wenigstens in band signaling zu haben. Die Entwicklung von IEEE 754 hat nichts mit C zu tun. In den 70ern gab es ein Sammelsurium verschiedener Fliesskommaformate, jeder Hersteller hatte eigene. C hingegen kannte damals kaum jemand. Dass man sich in diesem Rahmen auch um Grenzverhalten und unzulässige Operationen kümmert ist nur konsequent. Wobei IEEE 754 seinerseits abschaltbare Exceptions vorsieht. Die Sprache C andererseits verlangt bis heute nicht die Konformität zu IEEE 754 bzw. IEC 60559 und definiert auch kein bestimmtes Verhalten bei sigalling NaNs. Das sind einfach zwei verschiedene Paar Stiefel, entspricht es doch dem Leitmotiv, möglichst wenig Plattformspezifika in die Sprache hinein zu definieren. :
Bearbeitet durch User
Georg schrieb: > Axel Schwenke schrieb: >> Das nun ganz sicher nicht. Computer funktionieren deterministisch. > > Wie würdest du denn den Inhalt nicht initialisierter Variablen > bezeichnen? Klar arbeitet ein Prozessor deterministisch, aber für den > Programmierer ist der Inhalt nicht vorhersehbar. Und was läßt dich glauben, eine Divisionsroutine würde bei einer Division durch Null einfach den Inhalt einer nicht initialisierten Variablen zurückgeben? Mal abgesehen davon, daß ein solches Verhalten vom Standard gedeckt wäre: ich würde eine solche Laufzeitbibliothek mit maximaler Skepsis betrachten. XL Wow, was für eine Diskussion.
Mein Arduino sagt: Was ist 1/0 ? Es ist -1 Was ist 1/0 ? Es ist -1 Was ist 1/0 ? Es ist -1 Was ist 1/0 ? Es ist -1 Was ist 1/0 ? Es ist -1 Helge schrieb: > Mein Arduino sagt: ...was auch immer der Compiler zur Übersetzungszeit da reinschreibt. Viel interessanter ist der nicht konstante Fall, also was zur Laufzeit wirklich dann ausgerechnet wird. Aber da es sich um undefiniertes Verhalten handelt, kann das — selbst wenn man heute ein bestimmtes, nachvollziehbares Verhalten feststellen kann — schon übermorgen ganz anders aussehen. Der einzig korrekte Weg kann also nur sein, dass man den Divisor vor der Division gegen 0 testet und dann seine eigene Ausnahmebehandlung implementiert. :
Bearbeitet durch Moderator
Jörg Wunsch schrieb: > Helge schrieb: >> Mein Arduino sagt: > > ...was auch immer der Compiler zur Übersetzungszeit da reinschreibt. Nur schade dass der normale Arduino User absolut keine Vorstellung dieser zusammenhänge hat. Compiler, Linker, Präprozessor, Laufzeit alles ein dichter Nebel an Worthülsen der die Insel der Verzweiflung umweht. Paul Baumann schrieb: > Wenn ich den Text von Axel richtig verstanden habe, dann > gibt es auch da keine Fehlermeldung, wenn ich z.B. 2 Byte miteinander > multipliziere und das Ergebnis aus Versehen oder Unachtsamkeit auch > in eine Bytevariable hineinwürgen will? So ist es. C abstrahiert Register und ALU einer CPU zu Variablen und arithmetischen/logischen Operatoren. Leider fällt bei dieser Abstraktion auch das Flagregister der ALU mit hinten runter. Es wäre in vielen Fällen enorm hilfreich, die Flags auch auf Hochsprachenebene zur Verfügung zu haben. Die kanonische Lösung besteht darin, die Rechnung immer mit dem nächst- größeren Typ zu machen (bzw. allgemein einem Typ bei dem man sicher ist, daß er das Ergebnis in jedem Fall halten kann). Was natürlich immer dann zum Problem wird, wenn man Rechnungen mit dem längsten verfügbaren Typ macht. > Wenn das so ist, will ich kein "C" haben. Bei anderen Programmiersprachen bist du da auch nicht besser aufgehoben. Im Prinzip könnte man auch die C Laufzeitbibliothek so auslegen, daß sie in solchen Fällen einen Laufzeitfehler auslöst (wie es z.B. Turbopascal macht). Man macht es aber nicht, weil es den Code für den Normalfall (kein Überlauf) langsamer machen würde. Und auch weil nicht abfangbare Exceptions bäh sind. Gerade bei einem µC sollte das einleuchten. XL Axel Schwenke schrieb: > Mal abgesehen davon, daß ein solches Verhalten vom Standard gedeckt > wäre: ich würde eine solche Laufzeitbibliothek mit maximaler Skepsis > betrachten. In der PowerPC Spezifikation ist der Inhalt des Zielregisters bei einer ganzzahligen Division durch 0 undefiniert. Eine Exception ist damit nicht verbunden, jedenfalls nicht im Divisionsbefehl selbst. Es kann also durchaus sein, dass das Zielregister in diesem Fall nicht verändert wird. Wenn in diesem Register vorher eine echte Zufallszahl drin stand, dann hast du deine Division durch 0 mit echt zufälligem Ergebnis. Spass am Rande: Aus der Systematik der PowerPC Befehle ergeben sich Varianten von Divisionbefehlen, bei denen im Fall einer Division durch 0 weder eine Exception noch irgendein anderes definiertes Ergebnis vorliegt, auch keine Flags. Also schlicht nichts definiert ist. :
Bearbeitet durch User
@Axel Danke für Deine Antwort. Karl-Heinz schrub: >Dein heiss geliebtes BASCOM hat auch so seine Probleme. Richtig. Als Beweis dafür hänge ich ein Bild an, aus dem hervorgeht, daß eine Division durch Null zum Ergebnis 255 führt, wenn das Ergebnis als Byte dimensioniert ist. Als Single kommt Null heraus. Auch der Bascom- kompiler läßt sich also so einen Unfug gefallen. >> Wenn das so ist, will ich kein "C" haben. Jörg schrabte: >Das war das, was Karl Heinz „auf die Palme“ gebracht hat und was >er als „C-Bashing“ bezeichnet. Gut, dann muß ich im Forum "Markt" eine Annonce aufgeben, daß ich nach einer Goldwaage suche, auf die ich meine Worte legen kann... ;-) MfG Paul Paul Baumann schrieb: > Gut, dann muß ich im Forum "Markt" eine Annonce aufgeben, daß ich nach > einer Goldwaage suche, auf die ich meine Worte legen kann... Eine Laborwaage tut's auch. Wenn du keine hast, bei mir im Keller steht eine, schick die Worte einfach vorher zu mir, ich leg' sie dann mal drauf. ;-) Paul Baumann schrieb: > Danke für die Antworten auf meine Frage. Es stellt sich aber gleich > noch eine: Wenn ich den Text von Axel richtig verstanden habe, dann > gibt es auch da keine Fehlermeldung, wenn ich z.B. 2 Byte miteinander > multipliziere und das Ergebnis aus Versehen oder Unachtsamkeit auch > in eine Bytevariable hineinwürgen will? Nein, natürlich nicht. Könnte ja auch passen, Z.B. 1*1=1 paßt. > Wenn das so ist, will ich kein "C" haben. Das will man sowieso nicht. Allerdings hat das ganz andere Gründe. Numerische Überläufe ggf. auch ignorieren zu können, ist jedenfalls eine Eigenschaft einer Programmiersprache, die sowohl extrem nützlich als auch hochgefährlich sein kann. Wenn du das noch nicht begriffen hast, bist du ein Lamer, der sich aus solchen Diskussionen einfach mal raushalten sollte. So einfach ist das. Was passieren kann wurde ja bereits gesagt, wobei sich das auf int-Division bezieht: A. K. schrieb: > C definiert eine Division durch 0 als "undefiniert". Konkret: >> C99 3.4.3 undefined behavior >> >> behavior, upon use of a nonportable or erroneous program >> construct or of erroneous data, for which this International >> Standard imposes no requirements. >> >> NOTE >> >> Possible undefined behavior ranges from ignoring the >> situation completely with unpredictable results, to behaving >> during translation or program execution in a documented >> manner characteristic of the environment (with or without >> the issuance of a diagnostic message), to terminating a >> translation or execution (with the issuance of a diagnostic >> message). Helge schrieb: > Mein Arduino sagt: > > Was ist 1/0 ? Es ist -1 Und wer hat da jetzt gerechnet? War das der Compiler auf dem PC, der richtig erkannt hat, dass er die ganze Rechnung wegoptimieren kann und nur eine Konstante ausgeben muss, oder war das der AVR, der wirklich zwei Zahlen durch einen Algorithmus gejagt hat, den man im Quellcode mit "/" kennzeichnet? Da sollte man erstmal in den lst-File gucken, was der AVR zu dem Ergebnis beigetragen hat. >Und wer hat da jetzt gerechnet?
Das sollte Jörg beantworten können, er ist am nächsten drann beim
Compilerbau.
C-Hater erklärte großspurig: >Numerische Überläufe ggf. auch ignorieren zu können, ist jedenfalls eine >Eigenschaft einer Programmiersprache, die sowohl extrem nützlich als >auch hochgefährlich sein kann. Wenn du das noch nicht begriffen hast, >bist du ein Lamer, der sich aus solchen Diskussionen einfach mal >raushalten sollte. Nein, ich habe noch nicht begriffen, wozu das nützlich sein könnte. Aber Du kannst es ja mal kurz und prägnant erklären. Schließlich will ich ja kein Lamer sein, es reicht mir, mit verstauchtem Fuß ein Lahmer zu sein. SCNR Paul Helge schrieb: > Das sollte Jörg beantworten können, er ist am nächsten drann beim > Compilerbau. Nö, Johann. Hat sich ja schon ausreichend zu Wort gemeldet hier. Das "Ergebnis" kommt von den __[u]divmod{q,h,ps,s,d}i4 Routinen der libgcc, die im Falle von avr-gcc in Assembler implementiert sind. AFAIR liefern diese bei einem Divisor von 0 einen Quotienten, bei dem alle Bits gesetzt sind. Für den Rest kann es jeder bei Interesse selbst nachvollziehen: http://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/avr/lib1funcs.S?content-type=text%2Fplain&view=co Für die nicht zwingend saturierenden Fixed-Point Divisionen sind m.W. ebenfalls so, daß diese auf den Maximal- bzw. Minimal-Wert hin Saturieren. :
Bearbeitet durch User
Helge schrieb: > Das sollte Jörg beantworten können, er ist am nächsten drann beim > Compilerbau. Dafür brauchts keinen Compilerbau. Testcode übersetzen und reinsehen reicht. Ich selber würde es allerdings auch nicht dem Compiler, sondern der Runtime überlassen, damit sich ein konsistentes Verhalten ergibt, auch wenn das von der Sprache selbst nicht gefordert wird. Jörg Wunsch schrieb: > Der einzig korrekte Weg kann also nur sein, dass man den Divisor vor > der Division gegen 0 testet und dann seine eigene Ausnahmebehandlung > implementiert. Jörg, manchmal regst du mich auf. Eine NAN kriegt man auch bei Überläufen - und die gibt's dann AUCH, wenn der Divisor ungleich Null ist. Das Ergebnis braucht bloß zu groß zu sein. Wenn du (wie ich) massiv mit Meßwerten zu tun hast, wo Kunden irgendwo ihre Anlagen falsch einjustieren und dann sowas wie 1.234E+30/1.234E-33 zuwege bringen, dann klemmt es OHNE daß man als Programmierer viel dagegen tun kann, außer sowas wie if (fabs(x)<1E-29)... Weitaus besser wäre es, wenn bei all den saubescheuerten Gleitkomma-Libs genau SO verfahren worden wäre wie in der digitalen Signalverarbeitung, wo Übersteuerungen (die immer mal vorkommen) einfach durch sättigendes Verhalten abgefangen werden. Wenn dann mal 123/0 vorkommt, dann gibt das eben 7FFFFFFFh und fertig. Respektive -123/0 --> 80000000h Man macht bei sowas keinen wirklich relevanten Fehler und spart sich ne Menge Telefonate. W.S. W.S. schrieb: > Jörg, manchmal regst du mich auf. Eine NAN kriegt man auch bei > Überläufen Du uns auch: in diesem Thread geht es um ganzzahlige Divisionen, und da brauchen wir über NaNs nicht weiter zu diskutieren. Wenn du über Sinn und Unsinn von IEEE754 diskutieren willst, dann öffne bitte einen eigenen Thread. W.S. schrieb: > Weitaus besser wäre es, wenn bei all den saubescheuerten Gleitkomma-Libs > genau SO verfahren worden wäre wie in der digitalen Signalverarbeitung, Du bringst hier ein Beispiel, in dem saturierende Arithmetik sinnvoll ist. Es gibt andere, wo es geradezu kriminell leichtsinnig wäre, sinnvolle Ergebnisse vorzutäuschen, wo doch zur Laufzeit bereits bekannt ist, dass sie kompletter Unsinn sind. Leb damit, oder such dir eine Laufzeit oder Hardware, die deinen Wünschen entsprechend arbeitet. Wenn solches Verhalten bei DSPs wirklich bedeutend ist, dann sollte es welche geben, die sich entsprechend verhalten. Die Sprache C lässt das zu, sie verlangt nicht nach IEEE 754. :
Bearbeitet durch User
@Paul Mein C-Compiler(CVAVR) erkennt, wenn Multiplikationen oder Additionen möglicherweise zu Überläufen der Zielvarable führen ebenso erkennt er möglche Unterläufe und mögliche Nulldivisionen. Das alles meldet er während der Compilation. Ich habe dann die Möglichkeit dies zu ignorieren oder abzufangen. Meist habe ich die Varablen dann double oder long oder longlong definiert bzw. wenn der Definitonsbereich klar war und die Überschreitung nur theoretisch aber nicht real möglich war die Warnung ignoriert. Bis jetzt hatte ich damit nie ein Problem. Ich hatte das vor langem mal ausprobiert, es scheint so zu sein (tiny2313): irgendwas / 0 = alle Bits high 0 / 0 = 0 Simon S. schrieb: > Ich hatte das vor langem mal ausprobiert Trotzdem nochmal: das ist nicht garantiert, und kann und darf sich bereits mit der nächsten Version von Compiler oder Bibliothek ändern. @Wilfried Danke für Deine vernünftige Antwort. Das hat manch Einer hier nicht drauf, einfach nur eine Frage zu beantworten, ohne eine Axt hinterherzuwerfen. ;-) MfG Paul Route66 schrub: >Er heißt Winfried! Das kommt davon, daß mein Kollege Wilfried heißt. Grmmlhmpf! ;-) >Brille? - Wenigfrau! Wenigfrau? :-))) Wunderbar! Kannst Du mal meine Brille beschlagen? Ach, das wird mir jetzt ein bisschen fiel, Mann! MfG Paul Paul Baumann schrieb: > Wenigfrau? Eigentlich müsste es "Venigfrau" heissen. > Kannst Du mal meine Brille beschlagen? Gestell kaputt? Hufeisen vorm Kopp sehen aber ziemlich doof aus. :
Bearbeitet durch User
[NEBENBEI] Paul Baumann schrieb: > Wenn das so ist, will ich kein "C" haben. Wer das nicht versteht, wenn's von Paul kommt, den verstehe ich nicht! [/NEBENBEI] @Paul Vom Compiler zu verlangen, dass er sich um 'Division durch null' oder 'tan(90°)' kümmert, ist einfach Unsinn (sag ich jetzt mal so). Sicher ist das kein Problem, sowas zu integrieren, aber das schleppt man dann in jedem Programm mit rum! Jeden Sonderfall! Alles! Und das Ergebnis? Ist einfach falsch: W.S. schrieb: > Wenn dann mal 123/0 vorkommt, dann gibt das > eben 7FFFFFFFh und fertig. Respektive -123/0 --> 80000000h In vielen Fällen wird die Genauigkeit reichen. Aber mathematisch exakt ist das nicht. Wem das reicht, der setzt das in seinem Programm einfach selbst so um. Denn es geht in der Hauptanwendung von 'C' nicht um ein paar LED-Basteleien ;-) Paul Baumann schrieb: > Wenn ich den Text von Axel richtig verstanden habe, dann > gibt es auch da keine Fehlermeldung, wenn ich z.B. 2 Byte miteinander > multipliziere und das Ergebnis aus Versehen oder Unachtsamkeit auch > in eine Bytevariable hineinwürgen will? Genau aus dem gleichen Grund, wie oben. Vorher (kurz) überlegen, und dann nimmt man den richtigen Wertebereich. Ralf schrub:
>Vorher (kurz) überlegen, und dann nimmt man den richtigen Wertebereich.
Ja, ist ja richtig. Nur: Wem das noch nicht passiert ist, das falsche
Format für seine Ausgabe zu erwischen, der werfe mit dem ersten Trafo!
;-)
MfG Paul
Paul Baumann schrieb: > Nur: Wem das noch nicht passiert ist, das falsche > Format für seine Ausgabe zu erwischen, Das kommt sicher vor! "C" ist eben nicht für uns Bastler gedacht. Wir verwenden es nur. Aber wer da ernsthaft damit arbeitet (auch hobbymäßig), der schätzt den daraus resultierenden schlanken Code. (In jedem Beruf gibt's Stolperfallen!) 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
Noch kein Account? Hier anmelden.
|
|