Additions-Uebertrag
-
Hallo, ich habe eine Frage:
kann ich mich bei folgendem Code darauf verlassen, dass ein evtl.
Uebertrag ignoriert wird?uint8_t add_ints(uint8_t wert1, uint8_t) { return wert1+wert2; }
oder muss ich die Werte in einer uint16_t-Variable zwischenspeichern
und dann den Uebertrag entfernen:uint8_t add_ints(uint8_t wert1, uint8_t) { uint16_t summe = wert1 + wert2; summe &= 0xff; return (uint8_t)summe; }
Vielen Dank.
-
-
Und noch eine weitere Frage:
Gibt es eine Moeglichkeit, ohne 16-Bit-Zwischenvariable festzustellen,
ob ein Uebertrag stattgefunden hat?In Assembler wuerde ich einfach das Carry-Flag abfragen, kann ich in C aehnliches
machen?
-
gigg schrieb:
Gibt es eine Moeglichkeit, ohne 16-Bit-Zwischenvariable festzustellen, ob ein Uebertrag stattgefunden hat?
uint8_t add_ints(uint8_t wert1, uint8_t wert2) { uint8_t res = wert1+wert2; if(res<wert1) return -1; return res; }
-
-
Furble Wurble schrieb:
uint8_t ... return -1;
LOL
-
eghirzghrimsdrargn0r schrieb:
Furble Wurble schrieb:
uint8_t ... return -1;
LOL
So kommt man ganz einfach an den maximalen Wert!?
-
Nathan schrieb:
So kommt man ganz einfach an den maximalen Wert!?
gigg schrieb:
Gibt es eine Moeglichkeit, ohne 16-Bit-Zwischenvariable festzustellen,
ob ein Uebertrag stattgefunden hat?
-
eghirzghrimsdrargn0r schrieb:
Nathan schrieb:
So kommt man ganz einfach an den maximalen Wert!?
gigg schrieb:
Gibt es eine Moeglichkeit, ohne 16-Bit-Zwischenvariable festzustellen,
ob ein Uebertrag stattgefunden hat?Was ist denn?
-
Der Rueckgabewert muss unsigned int (uint8_t) sein, dann fallen negative Werte raus.
Ich mach mal ein Beispiel, was ich moechte:
0xf5 + 0xdd = 0x1d2
Ich brauche nur das Lowbyte als Rueckgabewert (0xd2).
Und ich muesste wissen, ob ein Uebertrag stattgefunden hat,
Wie kann man das moeglichst performant realisieren?
-
Furble Wurbles Lösung erkennt, ob ein Übertrag stattgefunden hat.
Es gab einen Übertrag, wenn das Ergebnis kleiner ist als der erste Wert.
Um das zu Kennzeichen wurde -1 zurückgegeben. -1 wird bei Konvertierung nach uint8_t zum maximal möglichen Wert gecastet.
Das ist so als ständ UINT_MAX oder wie das Makro heißt! Das ist kein negativer Wert!
-
Nathan schrieb:
Furble Wurbles Lösung erkennt, ob ein Übertrag stattgefunden hat.
Es gab einen Übertrag, wenn das Ergebnis kleiner ist als der erste Wert.
Um das zu Kennzeichen wurde -1 zurückgegeben. -1 wird bei Konvertierung nach uint8_t zum maximal möglichen Wert gecastet.
Das ist so als ständ UINT_MAX oder wie das Makro heißt! Das ist kein negativer Wert!Alles klar. jetzt hab ich's kapiert.
Danke euch.
-
gigg schrieb:
Alles klar. jetzt hab ich's kapiert.
hast du nicht
Nathan schrieb:
Furble Wurbles Lösung erkennt, ob ein Übertrag stattgefunden hat.
Es gab einen Übertrag, wenn das Ergebnis kleiner ist als der erste Wert.
Um das zu Kennzeichen wurde -1 zurückgegeben. -1 wird bei Konvertierung nach uint8_t zum maximal möglichen Wert gecastet.
Das ist so als ständ UINT_MAX oder wie das Makro heißt! Das ist kein negativer Wert!die "lösung" ist mangelhaft.
alle additionen deren ergebnis der maximalwert des bereichs uint8_t sind(z.b. 177+78), werden als überträge erkannt, die keine sind.
-
Nathan schrieb:
Furble Wurbles Lösung erkennt, ob ein Übertrag stattgefunden hat.
[...]
Das ist so als ständ UINT_MAX oder wie das Makro heißt! Das ist kein negativer Wert!
Was ist, wenn die Addition UINT_MAX ergibt?
-
gigg schrieb:
Wie kann man das moeglichst performant realisieren?
wenn ein größerer datentyp zur verfügung steht, so:
uint8_t a=0xf5, b=0xdd; int res; res = a+b; // :O if(res > INT8_MAX) puts("Wertebereich von uint8_t ueberschritten!");
-
eghirzghrimsdrargn0r schrieb:
gigg schrieb:
Wie kann man das moeglichst performant realisieren?
wenn ein größerer datentyp zur verfügung steht, so:
uint8_t a=0xf5, b=0xdd; int res; res = a+b; // :O if(res > INT8_MAX) puts("Wertebereich von uint8_t ueberschritten!");
Ok, danke, das entspricht meiner Loesung, die ich am Anfang hatte.
Ohne groesseren Datentypen geht es also nicht.
-
doch geht. eine überschreitung des wertebereichs lässt sich vorher abfragen, dafür kannst du fubels ansatz nehmen.
-
eghirzghrimsdrargn0r schrieb:
die "lösung" ist mangelhaft.
alle additionen deren ergebnis der maximalwert des bereichs uint8_t sind(z.b. 177+78), werden als überträge erkannt, die keine sind.LOL
Was gigg macht, nachdem er den Überlauf gesehen hat ist sein Bier:uint8_t add(uint8_t a, uint8_t b, int* overflow){ uint8_t sum = a+b; *overflow=sum<a; return sum; }
von mir aus.
eghirzghrimsdrargn0r schrieb:
uint8_t a=0xf5, b=0xdd; int res; res = a+b; // :O if(res > INT8_MAX) puts("Wertebereich von uint8_t ueberschritten!");
Schönes Ding...
-
Schoenes Ding? Sicher nicht, da es nicht auf bspw. uint64_t ueberteragbar ist.
-
knivil schrieb:
Schoenes Ding? Sicher nicht, da es nicht auf bspw. uint64_t ueberteragbar ist.
witzbold.
um uint64_t geht es hier überhaupt nicht.
-
Dumpfbatzen, ich habe ueber Schoenheit gerede, uint64_t war ein Beispiel.