Additions-Uebertrag



  • 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.



  • dann zeigen sie doch wie sie das ding schön machen würden und werden sie nicht gleich beleidigend sie vollpfosten!



  • #include <stdint.h>
    
    // für beliebige N:
    // testen vor der Addition:
    void func(uintN_t a, uintN_t b){
      if (UINTN_MAX - a < b)
        /* "Ueberlauf" */
      else
        /* ... */
    }
    
    // testen nach der Addition:
    void func(uintN_t a, uintN_t b){
      uintN_t sum = a + b;
      if (sum < a)
        /* "Ueberlauf" */
      else
        /* ... */
    }
    


  • "best-practice" ist folgendes, wobei das Interface aehnlich zu Intrinsics einiger Compiler ist:

    T addc(T a, T b, bool& carry)
    {
        T sum = a + b;
        carry = sum < a;
        return sum;
    }
    

    Eine Unterscheidung zw. vor und nach der Addition halte ich fuer unnoetig, da die Summanden sicher nach der Addition immernoch zur Verfuegung stehen.

    nicht gleich beleidigend sie vollpfosten!

    Aktion und Reaktion scheinen dir ein unbekanntes Konzept zu sein.


Anmelden zum Antworten