Ganzzahlige Divisionsrundung mit Negativen in C++

Lesezeit: 3 Minuten

Vermuten a und b sind beide vom Typ int, und b ist ungleich Null. Betrachten Sie das Ergebnis der Leistung a/b in folgenden Fällen:

  1. a und b sind beide nichtnegativ.
  2. a und b sind beide negativ.
  3. Genau einer davon ist negativ.

Im Fall 1 wird das Ergebnis auf die nächste ganze Zahl abgerundet. Aber was sagt die Norm zu den Fällen 2 und 3? Ein alter Entwurf, den ich im Internet gefunden habe, weist darauf hin, dass er implementierungsabhängig ist (ja, sogar Fall 2), aber das Komitee neigt dazu, ihn immer „auf Null zu runden“. Weiß jemand, was die (neueste) Norm sagt? Bitte antworten Sie nur basierend auf dem Standard, nicht was Sinn macht oder was bestimmte Compiler tun.

  • Unglaubliche Forschungsmöglichkeit angesichts der 1200-Seiten-Natur des Standards. Ich werde es schnell grep geben und aufgeben 🙂

    – Stefan Mai

    26. November 08 um 6:14 Uhr

Gemäß der Revision vom Mai 2008

Du hast recht:

Der binäre /-Operator liefert den Quotienten und der binäre %-Operator den Rest aus der Division des ersten Ausdrucks durch den zweiten. Wenn der zweite Operand von / oder % Null ist, ist das Verhalten undefiniert; andernfalls ist (a/b)*b + a%b gleich a. Wenn beide Operanden nichtnegativ sind, dann ist der Rest nichtnegativ; wenn nicht, ist das Vorzeichen des Rests implementierungsdefiniert75).

Anmerkung 75 sagt:

Gemäß den laufenden Arbeiten zur Überarbeitung von ISO C folgt der bevorzugte Algorithmus für die ganzzahlige Division den Regeln, die im ISO-Fortran-Standard ISO/IEC 1539:1991 definiert sind, in denen der Quotient immer auf Null gerundet wird.

Die Chancen stehen gut, dass C++ C in dieser Hinsicht hinterherhinken wird. So wie es aussieht, ist es undefiniert, aber sie haben ein Auge darauf, es zu ändern.

Ich arbeite in derselben Abteilung wie Stroustrup und mit einem Mitglied des Komitees. Dinge brauchen ALTER, um vollendet zu werden, und es ist endlos politisch. Wenn es albern erscheint, ist es wahrscheinlich.

  • Die zitierte Aussage ist alt. Es geht auf den C++98-Standard zurück und bezieht sich auf die C99-Revision. C99 gibt das Runden in Richtung Null an und C++11 folgt diesem Beispiel.

    – Jed

    29. Mai ’12 um 14:30 Uhr


Ganzzahlige Divisionsrundung mit Negativen in C
Sjoerd

Als Update zu den anderen Antworten:

Der letzte Entwurf von C++11, n3242 der für die meisten praktischen Zwecke identisch mit dem aktuellen C++11-Standard ist, heißt es in 5.6 Punkt 4 (Seite 118):

Für ganzzahlige Operanden liefert der /-Operator den algebraischen Quotienten, wobei alle Nachkommastellen verworfen werden; (siehe Anmerkung 80)

Anmerkung 80 besagt (beachten Sie, dass Anmerkungen nicht normativ sind):

80) Dies wird oft als Abschneiden in Richtung Null bezeichnet.

Punkt 4 heißt es weiter:

wenn der Quotient a/b in der Art des Ergebnisses darstellbar ist, ist (a/b)*b + a%b gleich a.

was gezeigt werden kann, um das Vorzeichen von zu erfordern a%b dasselbe sein wie das Zeichen von a (wenn nicht Null).

Nur ein Kommentar. Der aktuelle Arbeitsentwurf für den C++-Standard korrigiert tatsächlich das “implementierungsdefinierte” Problem und fordert eine Kürzung in Richtung Null. Hier ist die Webseite des Komitees, und Hier ist der Entwurf. Das Problem ist auf Seite 112.

Manchmal müssen wir einen Schritt zurücktreten und uns nur die Mathematik ansehen:

Gegeben int x, int y

wenn int i1 = x/y und int i2 = x%y

dann muss y * i1 + i2 x sein

Es geht also nicht so sehr um den Standard, sondern es gibt nur eine Möglichkeit, wie dies möglich sein kann. Wenn irgendein Standard es anders zulässt, dann ist der Standard falsch, und das bedeutet, dass die Sprache gebrochen ist.

.

620900cookie-checkGanzzahlige Divisionsrundung mit Negativen in C++

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy