Forum: PC-Programmierung gesättigte Arithmetik


von Studi (Gast)


Lesenswert?

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?!?!?

von (prx) A. K. (prx)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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);

von Studi (Gast)


Lesenswert?

Und was ist dann der nächste Wertebereich?
Ist das Ergebnis dann eine double-Zahl?

von Studi (Gast)


Lesenswert?

Ahhh stimmt ich meinte signed! ok dann hat sich's geklärt! Danke!

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Sven P. (Gast)


Lesenswert?


von Studi (Gast)


Lesenswert?

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?

von Klaus W. (mfgkw)


Lesenswert?

Auf welchem PC hat eine signed in nur 2 Byte?
Lebst du noch in DOS?

von Klaus W. (mfgkw)


Lesenswert?

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.

von Studi (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Bartli (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

Da dies unter "PC Programmierung steht": Für gesättigte 
Addition/Subtraktion haben x86er eigene SSE2-Befehle und Compiler 
üblicherweise irgendwelche Pseudo-Funktionen.

von Klaus W. (mfgkw)


Lesenswert?

e) die Hausaufgaben vom Forum erledigen lassen

Studi schrieb:
> ich möchte ein Programm schreiben,...

Studi schrieb:
> Ich muss ein Programm schreiben,...

von Studi (Gast)


Lesenswert?

Danke das werd ich mir jetzt mal durchlesen!

von Klaus W. (mfgkw)


Lesenswert?

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 :-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.