Arithmetische Operatoren
Gibt das Ergebnis einer bestimmten arithmetischen Operation zurück.
| Operatorname | Syntax | Prototypenbeispiele (für class T) | ||
|---|---|---|---|---|
| Innerhalb der Klassendefinition | Außerhalb der Klassendefinition | |||
| Unärer Plusoperator | +a | T T::operator+() const; | T operator+(const T& a); | |
| Unärer Minusoperator | -a | T T::operator-() const; | T operator-(const T& a); | |
| Addition | a + b | T T::operator+(const T2& b) const; | T operator+(const T& a, const T2& b); | |
| Subtraktion | a - b | T T::operator-(const T2& b) const; | T operator-(const T& a, const T2& b); | |
| Multiplikation | a * b | T T::operator*(const T2& b) const; | T operator*(const T& a, const T2& b); | |
| Division | a / b | T T::operator/(const T2& b) const; | T operator/(const T& a, const T2& b); | |
| Rest | a % b | T T::operator%(const T2& b) const; | T operator%(const T& a, const T2& b); | |
| Bitweises NICHT | ~a | T T::operator~() const; | T operator~(const T& a); | |
| Bitweises UND | a & b | T T::operator&(const T2& b) const; | T operator&(const T& a, const T2& b); | |
| Bitweises ODER | a | b | T T::operator|(const T2& b) const; | T operator|(const T& a, const T2& b); | |
| Bitweises XOR | a ^ b | T T::operator^(const T2& b) const; | T operator^(const T& a, const T2& b); | |
| Bitweises Links-Shift | a << b | T T::operator<<(const T2& b) const; | T operator<<(const T& a, const T2& b); | |
| Bitweises Rechts-Shift | a >> b | T T::operator>>(const T2& b) const; | T operator>>(const T& a, const T2& b); | |
| ||||
Inhalt |
[edit] Allgemeine Erklärung
Alle integrierten arithmetischen Operatoren berechnen das Ergebnis einer bestimmten arithmetischen Operation und geben ihr Ergebnis zurück. Die Argumente werden nicht geändert.
[edit] Umwandlungen
Wenn der Operand, der an einen integrierten arithmetischen Operator übergeben wird, ein ganzzahliger oder nicht-aufgezählter Enumerationstyp ist, dann wird er vor jeder anderen Aktion (aber nach der L-Wert-zu-R-Wert-Konvertierung, falls zutreffend) einer Ganzzahl-Promotion unterzogen. Wenn ein Operand einen Array- oder Funktionstyp hat, werden Array-zu-Zeiger- und Funktion-zu-Zeiger-Konvertierungen angewendet.
Für die binären Operatoren (außer Shifts) werden, wenn die getreppten Operanden unterschiedliche Typen haben, die üblichen arithmetischen Konvertierungen angewendet.
[edit] Überläufe
Vorzeichenlose Ganzzahlarithmetik wird immer modulo 2n
ausgeführt, wobei n die Anzahl der Bits in dieser bestimmten Ganzzahl ist. Z. B. für unsigned int ergibt das Hinzufügen von eins zu UINT_MAX 0, und das Subtrahieren von eins von 0 ergibt UINT_MAX.
Wenn bei der vorzeichenbehafteten Ganzzahlarithmetik ein Überlauf auftritt (das Ergebnis passt nicht in den Ergebnistyp), ist das Verhalten undefiniert — mögliche Manifestationen einer solchen Operation sind
- sie schlägt nach den Regeln der Darstellung um (typischerweise Zweierkomplement),
- sie löst eine Ausnahme aus — auf einigen Plattformen oder aufgrund von Compiler-Optionen (z. B.
-ftrapvin GCC und Clang), - sie sättigt auf den minimalen oder maximalen Wert (auf vielen DSPs),
- sie wird vom Compiler vollständig optimiert.
[edit] Gleitkommaumgebung
Wenn #pragma STDC FENV_ACCESS unterstützt wird und auf ON gesetzt ist, gehorchen alle Gleitkommaarithmetikoperatoren der aktuellen Gleitkomma- Rundungsrichtung und melden Gleitkommaarithmetikfehler wie in math_errhandling angegeben, es sei denn, sie sind Teil eines statischen Initialisierers (in diesem Fall werden keine Gleitkommaausnahmen ausgelöst und die Rundungsmodus ist auf "nächstliegend" gesetzt).
[edit] Gleitkomma-Kontraktion
Sofern #pragma STDC FP_CONTRACT nicht unterstützt und auf OFF gesetzt ist, kann die gesamte Gleitkommaarithmetik so ausgeführt werden, als hätten die Zwischenergebnisse unendliche Reichweite und Präzision, d. h., es sind Optimierungen zulässig, die Rundungsfehler und Gleitkommaausnahmen weglassen. Zum Beispiel erlaubt C++ die Implementierung von (x * y) + z mit einer einzigen fused multiply-add CPU-Instruktion oder die Optimierung von a = x * x * x * x; als tmp = x * x; a = tmp * tmp.
Unabhängig von der Kontraktion können Zwischenergebnisse der Gleitkommaarithmetik eine Reichweite und Präzision haben, die sich von der durch ihren Typ angezeigten unterscheidet; siehe FLT_EVAL_METHOD.
Formal garantiert der C++-Standard keine Genauigkeit von Gleitkommaoperationen.
[edit] Unäre arithmetische Operatoren
Die Ausdrücke unärer arithmetischer Operatoren haben die Form
+ Ausdruck |
(1) | ||||||||
- Ausdruck |
(2) | ||||||||
Die unären Operatoren + und - haben eine höhere Rangfolge als alle binären arithmetischen Operatoren, daher kann Ausdruck keine binären arithmetischen Operatoren auf oberster Ebene enthalten. Diese Operatoren assoziieren von rechts nach links.
+a - b; // equivalent to (+a) - b, NOT +(a - b) -c + d; // equivalent to (-c) + d, NOT -(c + d) +-e; // equivalent to +(-e), the unary + is a no-op if “e” is a built-in type // because any possible promotion is performed during negation already
[edit] Integrierte unäre arithmetische Operatoren
-a, wobei N die Anzahl der Bits nach der Promotion ist.
- Mit anderen Worten: Das Ergebnis ist das Zweierkomplement des Operanden (wobei Operand und Ergebnis als vorzeichenlos betrachtet werden).
[edit] Überladungen
Bei der Überladungsauflösung gegen benutzerdefinierte Operatoren nehmen für jeden cv-unqualifizierten getreppten arithmetischen Typ A und für jeden Typ T die folgenden Funktionssignaturen an der Überladungsauflösung teil
| A operator+(A) |
||
| T* operator+(T*) |
||
| A operator-(A) |
||
#include <iostream> int main() { char c = 0x6a; int n1 = 1; unsigned char n2 = 1; unsigned int n3 = 1; std::cout << "char: " << c << " int: " << +c << "\n" "-1, where 1 is signed: " << -n1 << "\n" "-1, where 1 is unsigned char: " << -n2 << "\n" "-1, where 1 is unsigned int: " << -n3 << '\n'; char a[3]; std::cout << "size of array: " << sizeof a << "\n" "size of pointer: " << sizeof +a << '\n'; }
Mögliche Ausgabe
char: j int: 106 -1, where 1 is signed: -1 -1, where 1 is unsigned char: -1 -1, where 1 is unsigned int: 4294967295 size of array: 3 size of pointer: 8
[edit] Additive Operatoren
Die Ausdrücke additiver Operatoren haben die Form
lhs + rhs |
(1) | ||||||||
lhs - rhs |
(2) | ||||||||
Die binären Operatoren + und - haben eine höhere Rangfolge als alle anderen binären arithmetischen Operatoren außer *, / und %. Diese Operatoren assoziieren von links nach rechts.
a + b * c; // equivalent to a + (b * c), NOT (a + b) * c d / e - f; // equivalent to (d / e) - f, NOT d / (e - f) g + h >> i; // equivalent to (g + h) >> i, NOT g + (h >> i) j - k + l - m; // equivalent to ((j - k) + l) - m
[edit] Integrierte additive Operatoren
Für integrierte binäre Plus- und binäre Minusoperatoren müssen beide Operanden prvalues sein und eine der folgenden Bedingungen muss erfüllt sein
- Beide Operanden haben einen arithmetischen oder nicht-aufgezählten Enumerationstyp. In diesem Fall werden für beide Operanden die üblichen arithmetischen Konvertierungen angewendet.
- Genau ein Operand hat einen Ganzzahl- oder nicht-aufgezählten Enumerationstyp. In diesem Fall wird eine Ganzzahl-Promotion auf diesen Operanden angewendet.
In der verbleibenden Beschreibung in diesem Abschnitt beziehen sich "Operand(en)", lhs und rhs auf die konvertierten oder getreppten Operanden.
- Beide Operanden haben einen arithmetischen Typ. In diesem Fall ist das Ergebnis die Summe der Operanden.
- Ein Operand ist ein Zeiger auf einen vollständig definierten Objekttyp, und der andere Operand hat einen ganzzahligen Typ. In diesem Fall wird der ganzzahlige Wert zum Zeiger addiert (siehe Zeigerarithmetik).
- Beide Operanden haben einen arithmetischen Typ. In diesem Fall ist das Ergebnis die Differenz, die sich aus der Subtraktion von rhs von lhs ergibt.
- lhs ist ein Zeiger auf einen vollständig definierten Objekttyp, und rhs hat einen ganzzahligen Typ. In diesem Fall wird der ganzzahlige Wert vom Zeiger subtrahiert (siehe Zeigerarithmetik).
- Beide Operanden sind Zeiger auf cv-qualifizierte oder cv-unqualifizierte Versionen desselben vollständig definierten Objekttyps. In diesem Fall wird rhs von lhs subtrahiert (siehe Zeigerarithmetik).
Wenn beide Operanden einen Gleitkommatyp haben und der Typ IEEE-Gleitkommaarithmetik unterstützt (siehe std::numeric_limits::is_iec559)
- Wenn ein Operand NaN ist, ist das Ergebnis NaN.
- Unendlichkeit minus Unendlichkeit ist NaN, und FE_INVALID wird ausgelöst.
- Unendlichkeit plus die negative Unendlichkeit ist NaN, und FE_INVALID wird ausgelöst.
[edit] Zeigerarithmetik
Wenn ein Ausdruck J, der einen ganzzahligen Typ hat, zu einem Ausdruck P vom Zeigertyp addiert oder subtrahiert wird, hat das Ergebnis den Typ von P.
- Wenn P zu einem Nullzeigerwert ausgewertet wird und J zu 0 ausgewertet wird, ist das Ergebnis ein Nullzeigerwert.
- Andernfalls, wenn P auf das
i-te Element eines Array-Objekts x mit n Elementen zeigt, gegeben den Wert von J als j, wird P wie folgt addiert oder subtrahiert
- Die Ausdrücke P + J und J + P
- zeigen auf das
i+j-te Element von x, wenn i + j im Bereich[0,n)liegt, und - zeigen auf die Position nach dem letzten Element von x, wenn i + j gleich n ist.
- zeigen auf das
- Der Ausdruck P - J
- zeigt auf das
i-j-te Element von x, wenn i - j im Bereich[0,n)liegt, und - zeigt auf die Position nach dem letzten Element von x, wenn i - j gleich n ist.
- zeigt auf das
- Andere j-Werte führen zu undefiniertem Verhalten.
- Andernfalls, wenn P auf ein vollständiges Objekt, ein Basisklassen-Teilobjekt oder ein Mitgliedsobjekt y zeigt, gegeben den Wert von J als j, wird P wie folgt addiert oder subtrahiert
- Die Ausdrücke P + J und J + P
- zeigt auf y, wenn j gleich 0 ist, und
- zeigt auf die Position nach y, wenn j gleich 1 ist.
- Der Ausdruck P - J
- zeigt auf y, wenn j gleich 0 ist, und
- zeigt auf die Position nach y, wenn j gleich -1 ist.
- Andere j-Werte führen zu undefiniertem Verhalten.
- Andernfalls, wenn P ein Zeiger auf die Position nach einem Objekt z ist, gegeben den Wert von J als j
- Wenn z ein Array-Objekt mit n Elementen ist, wird P wie folgt addiert oder subtrahiert
- Die Ausdrücke P + J und J + P
- zeigt auf das
n+j-te Element von z, wenn n + j im Bereich[0,n)liegt, und - zeigt auf die Position nach dem letzten Element von z, wenn j gleich 0 ist.
- zeigt auf das
- Der Ausdruck P - J
- zeigt auf das
n-j-te Element von z, wenn n - j im Bereich[0,n)liegt, und - zeigt auf die Position nach dem letzten Element von z, wenn j gleich 0 ist.
- zeigt auf das
- Andere j-Werte führen zu undefiniertem Verhalten.
- Andernfalls wird P wie folgt addiert oder subtrahiert
- Die Ausdrücke P + J und J + P
- zeigt auf z, wenn j gleich -1 ist, und
- zeigt auf die Position nach z, wenn j gleich 0 ist.
- Der Ausdruck P - J
- zeigt auf z, wenn j gleich 1 ist, und
- zeigt auf die Position nach z, wenn j gleich 0 ist.
- Andere j-Werte führen zu undefiniertem Verhalten.
- Andernfalls ist das Verhalten undefiniert.
Wenn zwei Zeigerausdrücke P und Q subtrahiert werden, ist der Typ des Ergebnisses std::ptrdiff_t.
- Wenn P und Q beide zu Nullzeigerwerten ausgewertet werden, ist das Ergebnis 0.
- Andernfalls, wenn P und Q auf das
i-te bzw.j-te Array-Element desselben Array-Objekts x zeigen, hat der Ausdruck P - Q den Wert i − j.
- Wenn i − j nicht durch std::ptrdiff_t darstellbar ist, ist das Verhalten undefiniert.
- Andernfalls, wenn P und Q auf dasselbe vollständige Objekt, Basisklassen-Teilobjekt oder Mitgliedsobjekt zeigen, ist das Ergebnis 0.
- Andernfalls ist das Verhalten undefiniert.
Diese Zeigerarithmetikoperatoren ermöglichen es Zeigern, die Anforderungen des LegacyRandomAccessIterator zu erfüllen.
Bei Addition und Subtraktion ist das Verhalten undefiniert, wenn P oder Q den Typ "Zeiger auf (möglicherweise cv-qualifiziertes) T" hat, wobei T und der Array-Elementtyp nicht ähnlich sind.
int arr[5] = {1, 2, 3, 4, 5}; unsigned int *p = reinterpret_cast<unsigned int*>(arr + 1); unsigned int k = *p; // OK, the value of “k” is 2 unsigned int *q = p + 1; // undefined behavior: “p” points to int, not unsigned int
[edit] Überladungen
Bei der Überladungsauflösung gegen benutzerdefinierte Operatoren nehmen für jedes Paar von getreppten arithmetischen Typen L und R und für jeden Objekttyp T die folgenden Funktionssignaturen an der Überladungsauflösung teil
| LR operator+(L, R) |
||
| LR operator-(L, R) |
||
| T* operator+(T*, std::ptrdiff_t) |
||
| T* operator+(std::ptrdiff_t, T*) |
||
| T* operator-(T*, std::ptrdiff_t) |
||
| std::ptrdiff_t operator-(T*, T*) |
||
wobei LR das Ergebnis der üblichen arithmetischen Konvertierungen von L und R ist.
#include <iostream> int main() { char c = 2; unsigned int un = 2; int n = -10; std::cout << " 2 + (-10), where 2 is a char = " << c + n << "\n" " 2 + (-10), where 2 is unsigned = " << un + n << "\n" " -10 - 2.12 = " << n - 2.12 << '\n'; char a[4] = {'a', 'b', 'c', 'd'}; char* p = &a[1]; std::cout << "Pointer addition examples: " << *p << *(p + 2) << *(2 + p) << *(p - 1) << '\n'; char* p2 = &a[4]; std::cout << "Pointer difference: " << p2 - p << '\n'; }
Ausgabe
2 + (-10), where 2 is a char = -8 2 + (-10), where 2 is unsigned = 4294967288 -10 - 2.12 = -12.12 Pointer addition examples: bdda Pointer difference: 3
[edit] Multiplikative Operatoren
Die Ausdrücke multiplikativer Operatoren haben die Form
lhs * rhs |
(1) | ||||||||
lhs / rhs |
(2) | ||||||||
lhs % rhs |
(3) | ||||||||
Multiplikative Operatoren haben eine höhere Rangfolge als alle anderen binären arithmetischen Operatoren. Diese Operatoren assoziieren von links nach rechts.
a + b * c; // equivalent to a + (b * c), NOT (a + b) * c d / e - f; // equivalent to (d / e) - f, NOT d / (e - f) g % h >> i; // equivalent to (g % h) >> i, NOT g % (h >> i) j * k / l % m; // equivalent to ((j * k) / l) % m
[edit] Integrierte multiplikative Operatoren
Für integrierte Multiplikations- und Divisionsoperatoren müssen beide Operanden einen arithmetischen oder nicht-aufgezählten Enumerationstyp haben. Für den integrierten Restoperator müssen beide Operanden einen Ganzzahl- oder nicht-aufgezählten Enumerationstyp haben. Für beide Operanden werden übliche arithmetische Konvertierungen angewendet.
In der verbleibenden Beschreibung in diesem Abschnitt beziehen sich "Operand(en)", lhs und rhs auf die konvertierten Operanden.
- Die Multiplikation einer NaN mit einer beliebigen Zahl ergibt NaN.
- Die Multiplikation einer Unendlichkeit mit Null ergibt NaN und FE_INVALID wird ausgelöst.
- Wenn ein Operand NaN ist, ist das Ergebnis NaN.
- Das Dividieren einer Zahl ungleich Null durch ±0,0 ergibt die korrekt vorzeichenbehaftete Unendlichkeit und FE_DIVBYZERO wird ausgelöst.
- Das Dividieren von 0,0 durch 0,0 ergibt NaN und FE_INVALID wird ausgelöst.
Hinweis: Bis zur Behebung des CWG-Problems 614 (N2757) war das Vorzeichen des Rests implementierungsabhängig, wenn einer oder beide Operanden des binären Operators % negativ waren, da es von der Rundungsrichtung der ganzzahligen Division abhing. Die Funktion std::div lieferte in diesem Fall ein wohldefiniertes Verhalten.
Hinweis: Für den Gleitkomma-Rest siehe std::remainder und std::fmod.
[edit] Überladungen
Bei der Überladungsauflösung für benutzerdefinierte Operatoren nehmen für jedes Paar von beförderten arithmetischen Typen LA und RA sowie für jedes Paar von beförderten ganzzahligen Typen LI und RI die folgenden Funktionssignaturen an der Überladungsauflösung teil:
| LRA operator*(LA, RA) |
||
| LRA operator/(LA, RA) |
||
| LRI operator%(LI, RI) |
||
wobei LRx das Ergebnis der gewöhnlichen arithmetischen Konvertierungen von Lx und Rx ist.
#include <iostream> int main() { char c = 2; unsigned int un = 2; int n = -10; std::cout << "2 * (-10), where 2 is a char = " << c * n << "\n" "2 * (-10), where 2 is unsigned = " << un * n << "\n" "-10 / 2.12 = " << n / 2.12 << "\n" "-10 / 21 = " << n / 21 << "\n" "-10 % 21 = " << n % 21 << '\n'; }
Ausgabe
2 * (-10), where 2 is a char = -20 2 * (-10), where 2 is unsigned = 4294967276 -10 / 2.12 = -4.71698 -10 / 21 = 0 -10 % 21 = -10
[edit] Bitweise logische Operatoren
Die Ausdrücke der bitweisen logischen Operatoren haben die Form:
~ rhs |
(1) | ||||||||
lhs & rhs |
(2) | ||||||||
lhs | rhs |
(3) | ||||||||
lhs ^ rhs |
(4) | ||||||||
Der bitweise NICHT-Operator hat eine höhere Präzedenz als alle binären arithmetischen Operatoren. Er assoziiert von rechts nach links.
~a - b; // equivalent to (~a) - b, NOT ~(a - b) ~c * d; // equivalent to (~c) * d, NOT ~(c * d) ~-e; // equivalent to ~(-e)
Es gibt eine Mehrdeutigkeit in der Grammatik, wenn auf ~ ein Typname oder ein decltype-Spezifizierer(seit C++11) folgt: Es kann entweder operator~ sein oder einen Destruktor-Identifikator einleiten. Die Mehrdeutigkeit wird aufgelöst, indem ~ als operator~ behandelt wird. ~ kann nur dort einen Destruktor-Identifikator einleiten, wo die Bildung eines operator~ syntaktisch ungültig ist.
Alle anderen bitweisen logischen Operatoren haben eine geringere Präzedenz als alle anderen binären arithmetischen Operatoren. Bitweises UND hat eine höhere Präzedenz als bitweises XOR, welches eine höhere Präzedenz als bitweises ODER hat. Sie assoziieren von links nach rechts.
a & b * c; // equivalent to a & (b * c), NOT (a & b) * c d / e ^ f; // equivalent to (d / e) ^ f, NOT d / (e ^ f) g << h | i; // equivalent to (g << h) | i, NOT g << (h | i) j & k & l; // equivalent to (j & k) & l m | n ^ o // equivalent to m | (n ^ o)
[edit] Eingebaute bitweise logische Operatoren
Für den eingebauten bitweisen NICHT-Operator muss rhs ein prvalue vom ganzzahligen oder nicht-aufgezählten Enumerationstyp sein, und eine ganzzahlige Promotion wird für rhs durchgeführt. Für andere eingebaute bitweise logische Operatoren müssen beide Operanden vom ganzzahligen oder nicht-aufgezählten Enumerationstyp sein, und gewöhnliche arithmetische Konvertierungen werden für beide Operanden durchgeführt.
In der verbleibenden Beschreibung in diesem Abschnitt beziehen sich "Operand(en)", lhs und rhs auf die konvertierten oder getreppten Operanden.
- Mit anderen Worten, das Ergebnis ist das Einerkomplement des Operanden (wobei Operand und Ergebnis als vorzeichenlos betrachtet werden).
[edit] Überladungen
Bei der Überladungsauflösung für benutzerdefinierte Operatoren nehmen für jedes Paar von beförderten ganzzahligen Typen L und R die folgenden Funktionssignaturen an der Überladungsauflösung teil:
| R operator~(R) |
||
| LR operator&(L, R) |
||
| LR operator^(L, R) |
||
| LR operator|(L, R) |
||
wobei LR das Ergebnis der üblichen arithmetischen Konvertierungen von L und R ist.
#include <bitset> #include <cstdint> #include <iomanip> #include <iostream> int main() { std::uint16_t mask = 0x00f0; std::uint32_t x0 = 0x12345678; std::uint32_t x1 = x0 | mask; std::uint32_t x2 = x0 & ~mask; std::uint32_t x3 = x0 & mask; std::uint32_t x4 = x0 ^ mask; std::uint32_t x5 = ~x0; using bin16 = std::bitset<16>; using bin32 = std::bitset<32>; std::cout << std::hex << std::showbase << "Mask: " << mask << std::setw(49) << bin16(mask) << "\n" "Value: " << x0 << std::setw(42) << bin32(x0) << "\n" "Setting bits: " << x1 << std::setw(35) << bin32(x1) << "\n" "Clearing bits: " << x2 << std::setw(34) << bin32(x2) << "\n" "Selecting bits: " << x3 << std::setw(39) << bin32(x3) << "\n" "XOR-ing bits: " << x4 << std::setw(35) << bin32(x4) << "\n" "Inverting bits: " << x5 << std::setw(33) << bin32(x5) << '\n'; }
Ausgabe
Mask: 0xf0 0000000011110000 Value: 0x12345678 00010010001101000101011001111000 Setting bits: 0x123456f8 00010010001101000101011011111000 Clearing bits: 0x12345608 00010010001101000101011000001000 Selecting bits: 0x70 00000000000000000000000001110000 XOR-ing bits: 0x12345688 00010010001101000101011010001000 Inverting bits: 0xedcba987 11101101110010111010100110000111
[edit] Bitweise Shift-Operatoren
Die Ausdrücke der bitweisen Shift-Operatoren haben die Form:
lhs << rhs |
(1) | ||||||||
lhs >> rhs |
(2) | ||||||||
Bitweise Shift-Operatoren haben eine höhere Präzedenz als bitweise logische Operatoren, aber eine geringere Präzedenz als additive und multiplikative Operatoren. Diese Operatoren assoziieren von links nach rechts.
a >> b * c; // equivalent to a >> (b * c), NOT (a >> b) * c d << e & f; // equivalent to (d << e) & f, NOT d << (e & f) g << h >> i; // equivalent to (g << h) >> i, NOT g << (h >> i)
[edit] Eingebaute bitweise Shift-Operatoren
Für die eingebauten bitweisen Shift-Operatoren müssen beide Operanden prvalues vom ganzzahligen oder nicht-aufgezählten Enumerationstyp sein. Ganzzahlige Promotions werden für beide Operanden durchgeführt.
In der weiteren Beschreibung in diesem Abschnitt beziehen sich "Operand(en)", a, b, lhs und rhs auf die konvertierten oder beförderten Operanden.
Wenn der Wert von rhs negativ ist oder kleiner als die Anzahl der Bits in lhs ist, ist das Verhalten undefiniert.
|
Für vorzeichenlose a ist der Wert von a << b der Wert von a * 2b Für vorzeichenbehaftete und nicht-negative a gilt: Wenn a * 2b Für negative a ist das Verhalten von a << b undefiniert. Für vorzeichenlose a sowie für vorzeichenbehaftete und nicht-negative a ist der Wert von a >> b der ganzzahlige Teil von a/2b Für negative a ist der Wert von a >> b implementierungsabhängig (in den meisten Implementierungen wird eine arithmetische Rechtsverschiebung durchgeführt, sodass das Ergebnis negativ bleibt). |
(bis C++20) |
|
Der Wert von a << b ist der eindeutige Wert, der kongruent zu a * 2b Der Wert von a >> b ist a/2b |
(seit C++20) |
Der Typ des Ergebnisses ist der Typ von lhs.
[edit] Überladungen
Bei der Überladungsauflösung für benutzerdefinierte Operatoren nehmen für jedes Paar von beförderten ganzzahligen Typen L und R die folgenden Funktionssignaturen an der Überladungsauflösung teil:
| L operator<<(L, R) |
||
| L operator>>(L, R) |
||
#include <iostream> enum { ONE = 1, TWO = 2 }; int main() { std::cout << std::hex << std::showbase; char c = 0x10; unsigned long long ull = 0x123; std::cout << "0x123 << 1 = " << (ull << 1) << "\n" "0x123 << 63 = " << (ull << 63) << "\n" // overflow in unsigned "0x10 << 10 = " << (c << 10) << '\n'; // char is promoted to int long long ll = -1000; std::cout << std::dec << "-1000 >> 1 = " << (ll >> ONE) << '\n'; }
Ausgabe
0x123 << 1 = 0x246 0x123 << 63 = 0x8000000000000000 0x10 << 10 = 0x4000 -1000 >> 1 = -500
[edit] Standardbibliothek
Arithmetische Operatoren sind für viele Standardbibliotheks-Typen überladen.
[edit] Unäre arithmetische Operatoren
| implementiert unäres + und unäres - (public member function of std::chrono::duration<Rep,Period>) | |
| wendet unäre Operatoren auf komplexe Zahlen an (function template) | |
| wendet einen unären arithmetischen Operator auf jedes Element des Valarrays an (public member function of std::valarray<T>) |
[edit] Additive Operatoren
| (C++11) |
führt Additions- und Subtraktionsoperationen mit einem Zeitpunkt durch (Funktionstemplate) |
| implementiert arithmetische Operationen mit Dauern als Argumente (Funktionstemplate) | |
| (C++20) |
addiert oder subtrahiert einen year_month_day und eine Anzahl von Jahren oder Monaten(Funktion) |
| verknüpft zwei Strings, einen String und ein char, oder einen String und string_view (function template) | |
| erhöht oder verringert den Iterator (public member function of std::reverse_iterator<Iter>)
| |
| erhöht oder verringert den Iterator (public member function of std::move_iterator<Iter>)
| |
| führt arithmetische Operationen mit komplexen Zahlen auf zwei komplexen Werten oder einer komplexen Zahl und einem Skalar durch (function template) | |
| wendet binäre Operatoren auf jedes Element zweier Valarrays oder eines Valarrays und eines Werts an (function template) |
[edit] Multiplikative Operatoren
| implementiert arithmetische Operationen mit Dauern als Argumente (Funktionstemplate) | |
| führt arithmetische Operationen mit komplexen Zahlen auf zwei komplexen Werten oder einer komplexen Zahl und einem Skalar durch (function template) | |
| wendet binäre Operatoren auf jedes Element zweier Valarrays oder eines Valarrays und eines Werts an (function template) |
[edit] Bitweise logische Operatoren
| führt binäre AND-, OR-, XOR- und NOT-Operationen durch (public member function of std::bitset<N>) | |
| führt binäre Logikoperationen auf Bitsets durch (function template) | |
| wendet einen unären arithmetischen Operator auf jedes Element des Valarrays an (public member function of std::valarray<T>)
| |
| wendet binäre Operatoren auf jedes Element zweier Valarrays oder eines Valarrays und eines Werts an (function template) |
[edit] Bitweise Shift-Operatoren
| wendet binäre Operatoren auf jedes Element zweier Valarrays oder eines Valarrays und eines Werts an (function template) | |
| führt binäre Links- und Rechtsschiebeoperationen durch (public member function of std::bitset<N>)
|
[edit] Stream-Einfüge-/Extraktionsoperatoren
In der gesamten Standardbibliothek sind bitweise Shift-Operatoren häufig mit I/O-Streams (std::ios_base& oder einer davon abgeleiteten Klasse) sowohl als linker Operand als auch als Rückgabetyp überladen. Solche Operatoren werden als *Stream-Einfüge*- und *Stream-Extraktions*-Operatoren bezeichnet.
| extrahiert formatierte Daten (public member function of std::basic_istream<CharT,Traits>) | |
| extrahiert Zeichen und Zeichen-Arrays (function template) | |
| fügt formatierte Daten ein (public member function of std::basic_ostream<CharT,Traits>) | |
| fügt Zeichendaten ein oder fügt in einen rvalue-Stream ein (function template) | |
| serialisiert und deserialisiert eine komplexe Zahl (function template) | |
| führt Stream-Ein- und -Ausgabe von Bitsets durch (function template) | |
| führt Stream-Ein- und -Ausgabe auf Strings durch (function template) | |
| (C++11) |
führt Stream-Ein- und -Ausgabe auf Pseudo-Zufallszahlengeneratoren durch (function template) |
| (C++11) |
führt Stream-Ein- und -Ausgabe auf Pseudo-Zufallszahlendistributionen durch (function template) |
[edit] Defect Reports
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 614 | C++98 | der algebraische Quotient der ganzzahligen Division war in implementierungsdefinierter Richtung gerundet |
der algebraische Quotient der ganzzahligen Division wird auf Null trunkiert (der gebrochene Teil wird verworfen) |
| CWG 1450 | C++98 | das Ergebnis von a / b war undefiniert, wenn es im Ergebnistyp nicht darstellbar ist |
das Verhalten von sowohl a / b als auch a % b ist in diesem Fall undefiniert |
| CWG 1457 | C++98 | das Verhalten des Verschiebens des linkensten 1-Bits einespositiven vorzeichenbehafteten Werts in das Vorzeichenbit war undefiniert |
wurde wohlformuliert |
| CWG 1504 | C++98 | ein Zeiger auf ein Basisklassen-Subobjekt eines Array- Elements konnte in der Zeigerarithmetik verwendet werden |
Das Verhalten ist in diesem Fall nicht definiert. |
| CWG 1515 | C++98 | nur vorzeichenlose ganze Zahlen, die unsigned deklarierten sollten die Gesetze der Arithmetik modulo 2n befolgen |
gilt für alle vorzeichenlosen ganzen Zahlen |
| CWG 1642 | C++98 | arithmetische Operatoren erlauben, dass ihre Operanden lvalues sind | einige Operanden müssen rvalues sein |
| CWG 1865 | C++98 | die Auflösung von CWG-Problem 1504 machte die Verhaltensweisen der Zeigerarithmetik, die Zeiger auf Array-Elemente betrifft, undefiniert, wenn der referenzierte Typ und der Array-Elementtyp unterschiedliche cv-Qualifikationen auf nicht-oberster Ebene haben |
wurde wohlformuliert |
| CWG 1971 | C++98 | es war unklar, ob die Regel, die die Mehrdeutigkeit von ~ auflöst, auf Fälle wie ~X(0) zutrifft |
die Regel gilt für solche Fälle |
| CWG 2419 | C++98 | ein Zeiger auf ein Nicht-Array-Objekt wurde nur als ein Zeiger auf das erste Element eines Arrays der Größe 1 in der Zeigerarithmetik behandelt, wenn der Zeiger durch & erhalten wurde |
gilt für alle Zeiger auf Nicht-Array-Objekte |
| CWG 2626 | C++98 | das Ergebnis des eingebauten operator~ war einfach'Einerkomplement' ohne korrekte Definition |
das Ergebnis wird in Begriffen der Basis-2-Darstellung formuliert |
| CWG 2724 | C++20 | die Rundungsrichtung der arithmetischen Rechtsverschiebung war unklar | wurde klargestellt |
| CWG 2853 | C++98 | ein Zeiger über das Ende eines Objekts konnte nicht mit einer ganzen Zahl addiert oder subtrahiert werden |
es kann |
[edit] Siehe auch
| Häufige Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung | Inkrement Dekrement |
Arithmetik | Logisch | Vergleich | Member Zugriff |
Sonstiges |
|
a = b |
++a |
+a |
!a |
a == b |
a[...] |
Funktionsaufruf a(...) |
| Komma a, b | ||||||
| Ternär a ? b : c | ||||||
| Spezielle Operatoren | ||||||
|
static_cast konvertiert einen Typ in einen anderen verwandten Typ | ||||||
| C-Dokumentation für Arithmetische Operatoren
|