Wie kann ich sicher Durchschnitt zweier unsigned ints in C++?

Unter Verwendung der integer-Mathematik allein, ich würde gerne "sicher" Durchschnitt zweier unsigned ints in C++.

Was ich meine "sicher" ist die Vermeidung von overflows (und alles andere, was gedacht werden kann).

Zum Beispiel, im Durchschnitt 200 und 5000 leicht:

unsigned int a = 200;
unsigned int b = 5000;
unsigned int average = (a + b) / 2; //Equals: 2600 as intended

Aber im Falle von 4294967295 und 5000, dann:

unsigned int a = 4294967295;
unsigned int b = 5000;
unsigned int average = (a + b) / 2; //Equals: 2499 instead of 2147486147

die beste, Die ich mir ausgedacht habe ist:

unsigned int a = 4294967295;
unsigned int b = 5000;
unsigned int average = (a / 2) + (b / 2); //Equals: 2147486147 as expected

Gibt es bessere Möglichkeiten?

  • Kann nicht, die du wirkst, die Summe zu long long?
  • Die Dritte option wird die falsche Antwort geben, wenn beide a und b sind ungerade, da es Runde, die sich beide Hälften).
  • US-patent mit der Nummer 6,007,232. Die Berechnung der Mittelwert von zwei integer-zahlen, die gerundet in Richtung null in einer einzigen Instruktion-Zyklus: google.com/patents?id=eAIYAAAAEBAJ&dq=6007232 im wesentlichen verwendet return (a >> 1) + (b >> 1) + (a & b & 0x1);
  • ...wow. Ich bin speichern, der link für das nächste mal, wenn jemand beschwert sich über software-Patente.
  • es ist interessant, wie viele Antworten enthalten diese patentierte Lösung. Ich bin sicher, dass die meisten/alle von Ihnen entwickelten es selbständig, vielleicht sogar auf der Stelle für Ihre Antwort. Das würde scheinen, zu zeigen das patent nicht erfüllen die Norm der nicht-Offensichtlichkeit.
  • dies ist ein hardware-patent (beachten Sie, dass das Ergebnis produziert wird in einem Taktzyklus)
  • Ich bin mir nicht sicher, das ist eine echte Auszeichnung. Der code @ArunSaha schrieb wird die CPU geworden, die Schaltung im patent beschriebene. Es kann sogar Arbeit in einem instruction-Zyklus auf einem modernen x86, aber ich bin mir nicht sicher. Unabhängig davon, daß C++ - code könnte trivial geändert in den VHDL-code, und dann ist es hardware...
  • York: sagen Sie, ops Antwort nicht funktioniert? er weiß. Wenn Ihr reden ArunSaha Kommentar oder sellibitze beantworten, dann haben Sie vergessen, die + (a & b & 0x1) Teil.

InformationsquelleAutor Tim | 2010-09-28
Schreibe einen Kommentar