Forum: Mikrocontroller und Digitale Elektronik Übertrag bei 32-Bit Addition


von Kapitän Blaubär (Gast)


Lesenswert?

Ich addiere zwei 32-Bit Zahlen.
1
VA = VB + VC;
Wie bekomme ich in C (GCC WinAVR) mit ob ein Übertrag erfolgt ist?
Wie kann ich das Carry-flag anzapfen?

von Karl H. (kbuchegg)


Lesenswert?

Kapitän Blaubär schrieb:
> Ich addiere zwei 32-Bit Zahlen.
>
1
> VA = VB + VC;
2
>
> Wie bekomme ich in C (GCC WinAVR) mit ob ein Übertrag erfolgt ist?

Wenn VC positiv ist und danach VA kleiner als VB ist, ist ein Übertrag 
entstanden.

> Wie kann ich das Carry-flag anzapfen?

Gar nicht.

von Maxx (Gast)


Lesenswert?

Oder den Datentyp ausreichend groß wählen, dass das 33. Bit (sonst im 
Carry) auch noch mit reinpasst.

von Kapitän Blaubär (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Wenn VC positiv ist und danach VA kleiner als VB ist, ist ein Übertrag
> entstanden.

1
unsigned long int VA, VB, VC;

Wie kann ich das testen ob Übertrag?
Kannst du coden?



MAXX schrieb:
>Oder den Datentyp ausreichend groß wählen, dass das 33. Bit (sonst im
>Carry) auch noch mit reinpasst.

Gibt es den einen Datentyp mit 40 Bit's?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

1
carry = 0;
2
a = b + c;
3
if (a < b) // oder a < c
4
   carry = 1;

Für signed-Werte ist das aber nicht mehr so einfach.

von Kapitän Blaubär (Gast)


Lesenswert?

Johann L. schrieb:
> carry = 0;
> a = b + c;
> if (a < b) // oder a < c
>    carry = 1;

Ich denke, beide Vergleiche sind nötig:
1
if ((a<b)||(a<c)) carry = 1;

Gibt's kein Assembler Template um das Carry-Flag anuzapfen?

von Stefan E. (sternst)


Lesenswert?

Kapitän Blaubär schrieb:
> Ich denke, beide Vergleiche sind nötig:

Nein. Oder schaffst du es, ein Beispiel zu konstruieren, wo nach dem 
Überlauf a zwischen b und c liegt?

von Maxx (Gast)


Lesenswert?

Nein es braucht nur den einen Vergleich du kannst dich auch den unsigned 
Fall beschränken. (Addition von signed und unsigned sind äquivalent auf 
der bit-ebene)

Nach einem Überlauf ist das ergebnis immer kleiner als jeder der beiden 
summanden. Grenzfäll sind 1111...1111 und 0000...0001, welches 
0000....0000 nach Überlauf ergibt und dieses echt kleiner eines jeden 
der beiden Sumanden ist, bzw 1111...1111 + 1111...1111 ergibt nach 
Überlauf 1111...1110.

D.h. nur einer der summanden muss getestet werden. Ist das Ergebnis nach 
der Addition unter Modulo 2^n kleiner als dder erste Summand, so ist es 
auch kleiner als der zweite Summand.

Achja, ein (u)int40 ist nicht intern definiert. Ein (u)int64 sollte man 
aber immer hinbekommen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Kapitän Blaubär schrieb:

> Gibt's kein Assembler Template um das Carry-Flag anuzapfen?

Nein. Nicht so, daß es wasserdicht ist.

Wenn, dann musst du die ganze Addition in (Inline) Assembler ausführen.
Dann bist du aber darauf festgelegt, immer auf GPRs zu operieren, 
während der Compiler bei der Addition einer Konstanten diese direkt 
addieren kann. In dem Fall hast du also 4 Befehler zum Laden der 
Konstanten und 4 Befehle für die Addition zuzüglich Carry-Extraktion.

Sieht mir aber verdächtig nach Angst-Optimierung™ aus...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Maxx schrieb:
> Nein es braucht nur den einen Vergleich du kannst dich auch den unsigned
> Fall beschränken. (Addition von signed und unsigned sind äquivalent auf
> der bit-ebene)

Nein, nicht wenn es um Überlauf-Erkennung/-Verarbeitung geht, wie man 
sie zB zur Saturierung braucht. Bei zwei 8-Bit Werten liefert zwar 
0xff+0xff=0xfe, aber eine signed-Addition läuft nicht über und bleibt im 
Wertebereich, während das für unsigned nicht der Fall ist.

Signed: -1+(-1)=-2 (ok)
Unsigned: 255+255=254 (nicht ok, und das will man erkennen)

Signed: 127 + 1 = -128 (nicht ok, will man erkennen)
Unsigned 127 + 1 = 128 (ok)

von Maxx (Gast)


Lesenswert?

Johann L. schrieb:
> Nein, nicht wenn es um Überlauf-Erkennung/-Verarbeitung geht, wie man
> sie zB zur Saturierung braucht. Bei zwei 8-Bit Werten liefert zwar
> 0xff+0xff=0xfe, aber eine signed-Addition läuft nicht über und bleibt im
> Wertebereich, während das für unsigned nicht der Fall ist.

Auch in diesem Fall ist das Carry-Flag gesetzt.
Auf Bit Ebene sind beide additionen identisch.

Es gibt keine getrennten Opcodes für Signed und Unsigned Additionen in 
2er Komplement Systemen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Maxx schrieb:
> Johann L. schrieb:
>> Nein, nicht wenn es um Überlauf-Erkennung/-Verarbeitung geht, wie man
>> sie zB zur Saturierung braucht. Bei zwei 8-Bit Werten liefert zwar
>> 0xff+0xff=0xfe, aber eine signed-Addition läuft nicht über und bleibt im
>> Wertebereich, während das für unsigned nicht der Fall ist.
>
> Auch in diesem Fall ist das Carry-Flag gesetzt.
> Auf Bit Ebene sind beide additionen identisch.
>
> Es gibt keine getrennten Opcodes für Signed und Unsigned Additionen in
> 2er Komplement Systemen.

Sagte ich auch nicht, aber die Behandlung ist anders, um einen Überlauf 
zu erkennen. Wird das Carry nur verwendet, um eine breitere Arithmetik 
aufzubauen, ist's natürlich gehopst wie gehoppelt.

Siehe zB AVR Arithmetik/Saturierung wo das Carry-Flag alleine nicht 
ausreicht.

Ebenso werden bei einem Vergleich andere Flags abgetestet, abhängig 
davon, ob er signed oder unsigned ausgeführt wird, obwohl die 
Vergleichs-OP intern nur eine Subtraktion (ohne Rückschreiben des 
Ergebnisses) ist.

von Maxx (Gast)


Lesenswert?

Wir suchen den Übertrag nicht den Überlauf.

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.