Hallo ich möchte ein Programm schreiben, dass alle vier Grundrechenarten unterstützt. Das habe ich bereits geschafft. Jetzt fehlt mir nur noch der Zusatz mit der gesättigten Arithmetik. Es soll bei einer Wertebereichsüberschreitungen das Ergebnis auf die nächstliegende Wertebereichsgrenze gesetzt werden. Sehe ich das richtig, dass wenn ich ein Ergebnis habe, welches den Wertebereich einer 16 Bit unsigned Zahl um 1 überschreitet, dann -32768 herauskommen muss?!?!?
Studi schrieb: > Sehe ich das richtig, dass wenn ich ein Ergebnis habe, welches den > Wertebereich einer 16 Bit unsigned Zahl um 1 überschreitet, dann -32768 > herauskommen muss?!?!? Nein.
Studi schrieb: > Sehe ich das richtig, dass wenn ich ein Ergebnis habe, welches den > Wertebereich einer 16 Bit unsigned Zahl um 1 überschreitet, dann -32768 > herauskommen muss? Nein. Wenn die Zahl kein Vorzeichen hat, hat sie kein Vorzeichen. Vermutlich hast Du signed gemeint, dann hättest Du recht.
1 | int i; |
2 | |
3 | i = 0x7fff; |
4 | |
5 | printf("%d\n", i); |
6 | |
7 | i++; |
8 | |
9 | printf("%d\n", i); |
Und was ist dann der nächste Wertebereich? Ist das Ergebnis dann eine double-Zahl?
Rufus Τ. Firefly schrieb: > Vermutlich hast Du signed gemeint, dann hättest Du recht. Nicht zwangsläufig. Das Verhalten ist undefiniert. Jedenfalls wenn C/C++ gemeint sein sollte. Da der Compiler das weiss kann es auch tatsächlich zu abweichendem Verhalten kommen.
Studi schrieb: > Ahhh stimmt ich meinte signed! ok dann hat sich's geklärt! Danke! Das Überlaufverhalten von Integers ist in C/C++ nur für vorzeichenlose Datentypen klar definiert. Bei Datentypen mit Vorzeichen sollte man nicht von einem bestimmten Verhalten ausgehen.
'Undefiniertes Verhalten' schließt dabei einen Programmabsturz mit ein. Näheres dazu: https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
Hm das war nicht richtig! signed integer hat einen Zahlenwert von -32768 bis 32767. Wenn ich nun 32767 + 1 rechne, soll 32767 als Ergebnis heraus kommen, da dies näher an dem richtigen Ergebnis dran ist als die -32768. Nur wie mache ich das?
Es gibt doch im großen Netz etliche Texte, wie man so etwas realisiert. Ich habe es nie genutzt (und wenn, dann würde ich es nicht in C, sondern C++ machen). Auf jeden Fall muß man VOR jeder Operation schauen, ob es noch passt, z.B. indem man vor einer Addition einen Summanden vom größtmöglichen Ergebnis abzieht und mit dem anderen vergleicht. Das Ganze natürlich abhängig von den Vorzeichen der Operanden... So richtig effizient wird das nicht werden, und in C auch nicht schön zu schreiben, weil man i+j nicht auf die eigenen Operationen umbiegen kann, sondern sowas wie add_signed_int_saturated( i, j ) schreiben müsste.
Mein Problem nochmal: Ich muss ein Programm schreiben, welches bei einer Wertebereichsüberschreitung, den höchsten Wert des Wertebereichs angibt. Ich muss 16 Bit Integer verwenden. Mein h-file ist oben.
a) Überlauf detektieren so wie beschrieben (https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow) und dann eben ggf. 32767 als Ergebnis verwenden. b) Operanden und Zwischenergebnis auf nächstbreiteren Typ umwandeln und dort den Überlauf abfangen. c) MMX verwenden. d) Aufgeben.
Da signed Arithmetik bei dir offenbar zu einem Überlauf führt: Wie wäre es einfach mal die Ergebnisse zu vergleichen? Wenn du zu einer Zahl X etwas postives Y dazuzählst, dann muss das Ergebnis offensichtlich größer als X sein. Kommt bei deiner Rechnung etwas kleineres raus (zb +32768 + 1 -> -32767, -32767 ist kleiner als +32768), dann gab es ziemlich offensichtlich einen Überlauf. Reicht dir das als Hinweis? Man kann sich aber zb auch voerher ausrechnen, wieviel man zu einer Zahl X noch maximal dazuaddieren kann, bis man am größtmöglichen Wert ist. Wenn dann die Zahl Y größer als dieser errechnete Maximalwert ist, dann wird die Addition wohl in die Hose gehen. Es ist nicht verboten, zwischen Zahlen nach Zusammenhängen zu suchen und sich selbst ein paar Zusammenhänge durch Probieren und Überlegen zu erschliessen. Dann kann man das Ganze auch programmieren. Aber irgendwann wird es Zeit, auf eigenen Beinen zu stehen und die Sicherheit von vorgekauten Patentrezepten zu verlassen.
Da dies unter "PC Programmierung steht": Für gesättigte Addition/Subtraktion haben x86er eigene SSE2-Befehle und Compiler üblicherweise irgendwelche Pseudo-Funktionen.
e) die Hausaufgaben vom Forum erledigen lassen Studi schrieb: > ich möchte ein Programm schreiben,... Studi schrieb: > Ich muss ein Programm schreiben,...
A. K. schrieb: > Da dies unter "PC Programmierung steht": Für gesättigte > Addition/Subtraktion haben x86er eigene SSE2-Befehle und Compiler > üblicherweise irgendwelche Pseudo-Funktionen. Wahrscheinlich nicht im Sinne der Aufgabenstellung :-)
Karl Heinz Buchegger schrieb: > Wie wäre es einfach mal die Ergebnisse zu vergleichen? > > Wenn du zu einer Zahl X etwas postives Y dazuzählst, dann muss das > Ergebnis offensichtlich größer als X sein. Kommt bei deiner Rechnung > etwas kleineres raus (zb +32768 + 1 -> -32767, -32767 ist kleiner als > +32768), dann gab es ziemlich offensichtlich einen Überlauf. > > Reicht dir das als Hinweis? Nein, denn in C ist Signed-Ünberlauf undefined, so daß diese Vorgehensweise nicht C-konform ist. GCC kennt die Option -fno-strict-overflow, welche aber nicht portabel ist.
Johann L. schrieb: >> Reicht dir das als Hinweis? > > Nein, denn in C ist Signed-Ünberlauf undefined, so daß diese > Vorgehensweise nicht C-konform ist. Drum hab ich den Artikel auch mit > Da signed Arithmetik bei dir offenbar zu einem Überlauf führt: begonnen und hinten nach noch eine Alternative offeriert.
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.