Überläufe verhindern
-
Wenn ich eine unsigned char Variable zu einer unsigend long addiere und sie vorher multipliziere, kann es zum Überlauf kommen?
Beispiel:
unsigned long a = 0;
unsigned char b = 200;a += b * 65536; // Überlauf von b?
a += (unsigned long)b * 256; // Besser so?// Oder am besten so?
unsigned long c = 65536 * b;
a += c;Danke im Voraus.
-
AnfängerC schrieb:
Wenn ich eine unsigned char Variable zu einer unsigend long addiere und sie vorher multipliziere, kann es zum Überlauf kommen?
Bei jeder Addition kann was überlaufen. Die Frage ist immer, wie breit die Typen sind. Deine Beispiele laufen auf handelsüblichen PCs wahrscheinlich nicht über, weil beim Rechnen alles zumindest auf
int
verbreitert wird. Wenn du einen Überlauf befürchtest, solltest du prüfen, ob einer passiert ist.
-
mngbd schrieb:
Wenn du einen Überlauf befürchtest, solltest du prüfen, ob einer passiert ist.
Wie geht das?
:):)
:):)
-
AnfängerC schrieb:
a += b * 65536; // Überlauf von b?
Da kann die Multiplikation überlaufen, denn die wird als signed int oder signed long gerechnet.
a += (unsigned long)b * 256; // Besser so?
Ja, so wird sowohl die Multiplikation als auch die Addition als unsigned long gemacht, es kann also nichts überlaufen (und mit deinen Zahlen auch nicht rumwrappen).
// Oder am besten so?
unsigned long c = 65536 * b;
a += c;Das macht dasselbe wie das erste.
-
Danke, namespace invader!
-
namespace invader schrieb:
a += (unsigned long)b * 256; // Besser so?
Ja, so wird sowohl die Multiplikation als auch die Addition als unsigned long gemacht, es kann also nichts überlaufen (und mit deinen Zahlen auch nicht rumwrappen).
#include <stdio.h> #include <stdlib.h> int main(void) { unsigned char a = 0xff; unsigned char b = 0x03; unsigned char c = a+b; printf("%d",c); return 0; }
das hat doch mit signed und unsigned nix zu tun oder etwa doch
lg lolo
-
Der Compiler führt Rechenoperationen immer mit dem grössten daran
beteiligten Datentyp durch. Bei Zahlen geht der Compiler von int aus
wenn nichts angegeben ist und der Wert "reinpasst".Wenn man also zwei int addiert oder multipliziert findet ein Überlauf statt,
den der Compiler beim Übersetzen übersehen kann. Wenn der übergelaufene Wert
der Ergebnisvariable (kann ruhig long sein) zugewiesen wird ist es schon zu
spät und das Ergebnis ist FALSCH.VG
Merano
-
noobLolo schrieb:
das hat doch mit signed und unsigned nix zu tun oder etwa doch
Nagut, für den konkreten Fall ist eher die Frage long oder int wichtig.
Ein Überlauf im Sinne des Standards kann aber nur bei signed auftreten. Und der ist dann auch Undefinied Behavior, man sollte also sicherstellen, dass so etwas gar nicht erst passiert, also nicht erst nachträglich versuchen herauszubekommen, ob einer stattgefunden hat.
Bei unsigned kommt immer das richtige Ergebnis raus, nur wird eben nicht mit natürlichen Zahlen gerechnet, sondern modulo maximalwert+1. Also wenn etwas zu groß wird, kommt es wieder bei 0 an.
Das könnte man natürlich auch als Überlauf bezeichnen, zumindest wird es wohl meist nicht das im Sinne des Programms richtige Ergebnis sein.