C51: int & Modulo vs. char (Prüfsumme)



  • Hallo mal wieder allerseits,

    ich habe mal wieder das Gefühl ich bin von starrköpfigen Menschen umgeben oder habe etwas übersehen 😞 :

    Ein C-Programm enthält eine Funktion die serielle Datenübertragung realisiert. Die serielle Datenübertragung ist an ein selbst definiertes Protokoll gebunden. Nun soll über alle Datenbytes eines zu sendenden Rahmen eine einfache Prüfsumme gebildet bzw. für empfangene Rahmen die Prüfsumme kontrolliert werden. Dies soll durch einfache Addition der einzelnen Hex-Bytes (jeweils 8Bit) geschehen.
    In einer Protokollvorlage von einem Kollegen wird das jeweilige Ergebnis der Addition in einer 16-Bit Integer-Variablen abgelegt und am Ende mit Modulo 256 (%256 - ergibt den Rest der ganzzahligen Division) die endgültige Prüfsumme errechnet.
    Nun bin ich der Meinung eine 8-Bit char-Variable würde genügen um die Prüfsumme zu bilden und man könnte zusätzlich die Modulo-Berechnung einsparen. Der Kollege meinte aber er hätte das mal so übernommen, es wird schon seinen Sinn haben und ich möchte es so lassen. Es interessiert mich trotzdem, ob mein Weg besser wäre (wenn auch nur geringfügig).

    Beispiel:

    // meine Version:
    unsigned char ucPrüfSumme= 0x00;    // 8-Bit-Variable
    ucPrüfSumme= 0xCA;
    ucPrüfSumme+= 0x04;
    ucPrüfSumme+= 0xFF;
    ucPrüfSumme+= 0xAD;
    ucPrüfSumme+= 0xB5;    // die Prüfsumme ist jetzt 0x2F
    ucPrüfSumme+= 0xCC;    // die Prüfsumme ist jetzt 0xFB
    ucPrüfSumme+= 0xA9;    // die Prüfsumme ist jetzt 0xA4
    
    // die Version vom Kollegen:
    unsigned int uiPrüfSumme= 0x00;    // 16-Bit-Variable
    uiPrüfSumme= 0xCA;
    uiPrüfSumme+= 0x04;
    uiPrüfSumme+= 0xFF;
    uiPrüfSumme+= 0xAD;
    uiPrüfSumme+= 0xB5;    // die Prüfsumme ist jetzt 0x032F
    // uiPrüfSumme%= 256; => würde 0x002F für die Prüfsumme ergeben
    uiPrüfSumme+= 0xCC;    // die Prüfsumme ist jetzt 0x03FB
    // uiPrüfSumme%= 256; => würde 0x00FB für die Prüfsumme ergeben
    uiPrüfSumme+= 0xA9;    // die Prüfsumme ist jetzt 0x04A4
    uiPrüfSumme%= 256;    // die Prüfsumme ist jetzt 0x00A4
    

    Habe ich etwas übersehen oder seid Ihr auch der Meinung, dass beide Verfahren zum selben Ergebnis führen?



  • Ich würde es auch mit einem einzelnen unsigned char machen, das führt auf jeden Fall zum gleichen Ergebnis und ist auf einem 8-Bit-µC auch um einiges schneller.



  • Vom Ergebnis sollten beide Varianten zum selben Ergebnis führen (beim Speichern in unsigned char wird effektiv auch mit %256 der höherwertige Anteil abgeschnitten). Allerdings könnte es etwas schneller gehen, dauerhaft mit int zu rechnen, als wenn du erst jedes Eingabezeichen in int umwandelst, addierst und anschließend wieder zurückwandelst in char.



  • Danke für Eure Antworten,

    @Bashar: ja, so war auch mein Denkansatz.

    @C.Stoll: ich sende und empfange als char bzw. in/aus Puffer (char-Arrays). Daher muss ich nichts wandeln, sondern kann einfach die chars addieren. Oder habe ich Dich falsch verstanden?



  • C kann keine char's addieren, darum werden die Operanden für Rechenoperationen automatisch in int umgewandelt und dann verrechnet (das nennt sich "integral promotion", falls du mehr Inforamtionen benötigst).



  • so eine prüfsummenberechnung, noch dazu wenn die oberen 8 bits abgeschnitten werden, ist nicht besonders brauchbar. nimm besser 'nen CRC oder sowas: http://en.wikipedia.org/wiki/Fletcher's_checksum
    🙂



  • CStoll schrieb:

    C kann keine char's addieren, darum werden die Operanden für Rechenoperationen automatisch in int umgewandelt

    und da ein 'int' in C mindestens 16 bits haben muss, darf ein standardkonformer compiler selbst auf einem 8-bitter nicht mit bytes rechnen d.h. es bleibt einem nichts anderes übrig, für maximale perdormance die funktion in assembler zu schreiben.
    oder wie jetzt?
    🙂



  • @C.Stoll:

    C.Stoll schrieb:

    C kann keine char's addieren...

    Ich war der Meinung mein 8051-kompatibler 8-bit-µC, für den ich Programme in C51 (siehe Titel) schreibe, rechnet lieber (bzw. ist optimiert für Berechnungen) mit Byte-Werten, statt mit 2-Byte-Werten!? 😕
    @Ghost Propeller: Das war doch das was Du meintest, oder? 😕

    @Protocol Designer: Das Protokoll ist nicht von mir und ich werde erstmal nicht weiter daran herummäkeln - erst recht nicht, wenn schon so Kleinigkeiten (wie der Grund für diesen Thread hier) mit unverhältnismäßiger Überzeugungsarbeit verbunden sind. 🙄
    Unabhängig davon, war mir dieser Einwand auch schon in den Kopf geschossen.



  • Kolumbus schrieb:

    @Ghost Propeller: Das war doch das was Du meintest, oder? 😕

    ja, eigentlich doof, ne?
    naja, bestimmt haben manche compiler switches, mit denen man diese blöden 'integer promotions' temporär abschalten kann.
    🙂



  • Demonizer schrieb:

    naja, bestimmt haben manche compiler switches, mit denen man diese blöden 'integer promotions' temporär abschalten kann.
    🙂

    Soweit ich mich erinnere, hat der C51 einen Schalter, mit dem man die integer promotions erzwingen kann. Standardmäßig rechnet er "vernünftig" 😉



  • Bashar schrieb:

    Soweit ich mich erinnere, hat der C51 einen Schalter, mit dem man die integer promotions erzwingen kann. ...

    Echt? 😮 Das wusste ich nicht, den Schalter werd' ich mal suchen!

    Also hatte am Ende alle Schreiber hier irgendwie Recht!?! 🙂


Log in to reply