Die Subtraktion in C++ (Die Subtraktion in C++, Minus, binärer Minusoperator), Lektion, Seite 722468
https://www.purl.org/stefan_ram/pub/subtraktion_c++_de (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
C++-Kurs

Die Subtraktion »…-…« in C++ 

Das Zeichen »-« wird „Minus“ oder „Bindestrich“ genannt. Die Subtraktion wird mit dem Minus »-« geschrieben.

Syntax, Typanforderungen, Typergebnisse, Assoziativität und Priorität sind bei diesem binären Operator wie bei der Addition. Die Semantik ist hingegen die der Subtraktion.

Neue, erweiterte Syntax

Primaerausdruck

.----------.
---.------------>| Literal |------------.--->
| '----------' |
| .-. .----------. .-. |
'--->( ( )--->| Ausdruck |--->( ) )---'
'-' '----------' '-'

unaerer Ausdruck

.-----------------.
---.------------>| Primaerausdruck |------------.--->
| '-----------------' |
| .------------. .-----------------. |
'--->| Vorzeichen |--->| Primaerausdruck |---'
'------------' '-----------------'

Vorzeichen

.-.
---.--->( + )---.--->
| '-' |
| .-. |
'--->( - )---'
'-'

multiplikativer Ausdruck

.------------------.
---.--------------------------------------------->| unaerer Ausdruck |---.--->
| '------------------' |
| .---------------------------. .-. .------------------. |
'--->| multiplikativer Ausdruck |--->( * )--->| unaerer Ausdruck |---'
| '---------------------------' '-' '------------------' |
| .---------------------------. .-. .------------------. |
'--->| multiplikativer Ausdruck |--->( / )--->| unaerer Ausdruck |---'
'---------------------------' '-' '------------------'

additiver Ausdruck

.--------------------------.
---.-------------------------------------->| multiplikativer Ausdruck |---.--->
| '--------------------------' |
| .--------------------. .-. .--------------------------. |
'--->| additiver Ausdruck |--->( + )--->| multiplikativer Ausdruck |---'
| '--------------------' '-' '--------------------------' |
| .--------------------. .-. .--------------------------. |
'--->| additiver Ausdruck |--->( - )--->| multiplikativer Ausdruck |---'
'--------------------' '-' '--------------------------'

Ausdruck

.--------------------.
--->| additiver Ausdruck |--->
'--------------------'

Subtraktion zur Erkennung eines Unterschiedes

Die Subtraktion kann gut verwendet werden, um zu erkennen, ob zwei Werte den gleichen Zahlenwert repräsentieren: Nur dann ist ihre Differenz gleich 0.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 0 - 0.00 << "\n"s; }

::std::cout
0

Der Wert von »0« ist ja zunächst nicht gleich dem Wert von »0.00«, da beide Werte sich schon im Typ unterscheiden. Da bei dieser Subtraktion der Typ der beiden Operanden jedoch nach »double« angeglichen wird, ergibt sich dann doch das Ergebnis »0.0«.

Der Wert »1.0000001« und der Wert »1.000000001« werden beide in der gleichen Weise ausgegeben.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 1.0000001 << "\n"s; }

::std::cout
1
main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 1.000000001 << "\n"s; }

::std::cout
1

Durch Berechnung der Differenz  von »1.0000001« und »1.000000001« wird aber ein Unterschied sichtbar.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 1.0000001 - 1.000000001 << "\n"s; }

::std::cout
9.9e-008

Unter manchen Implementationen wird der Wert von »1.999999« als »2« ausgegeben.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 1.999999 << "\n"s; }

::std::cout
2

Durch Berechnung der Differenz zu »2« kann man aber erkennen, daß der Wert sich von »2« unterscheidet.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 1.999999 - 2 << "\n"s; }

::std::cout
-1e-006

Die Ausgabe »2« erfolgt nur, weil der Wert zur Ausgabe auf sechs Nachkommastellen gerundet wurde, intern werden aber noch etwas mehr Stellen gespeichert (die genaue Anzahl dieser Stellen hängt aber von der verwendeten C++ -Implementation ab.)

Es wird noch einmal deutlich, daß verschiedene  Literale denselben  Wert haben können, also sind Literale nicht dasselbe wie ihre Werte.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 2 - 1.999999999999999999999999999999999999999999999999999999999999999999999 << "\n"s; }

::std::cout
0

(Das obenstehende Programm muß nicht unter allen C++ -Implementationen »0« ausgeben. Ein Implementation, welche sehr genau rechnet, könnte auch eine positive Differenz ausgeben.)

Die Subtraktion kann kleine Unterschiede zwischen zwei Werten verdeutlichen.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 9'007'199'254'740'992. - 9'007'199'254'740'991. << "\n"s; }

Protokoll
1

Wenn die Zahlen zu groß werden, werden die hinteren Stellen vom Datentyp »double« nicht mehr korrekt dargestellt, so daß die Ergebnisse nach der Schulmathematik nicht mehr korrekt sind.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 9'007'199'254'740'993. - 9'007'199'254'740'992. << "\n"s; }

Protokoll
0

Der Datentyp »double« stellt Zahlen mit Nachkommastellen auch nur näherungsweise dar. Die kleinen Unterschiede der Näherungen werden durch die Subtraktion hervorgehoben. Das Ergebnis der Rechnung ist nach der Schulmathematik ebenfalls wieder falsch.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << 0.1 + 0.2 - 0.3 << "\n"s; }

Protokoll
5.55112e-017

Wir zeigen hier die intern vollzogene Rechnung mit einer Dezimaldarstellung der Werte, wie sie bei einer typischen C++ -Implementation im Jahre 2018 verwendet werden könnten. (Diese Werte sind alle Summen von Zweierpotenzen, weswegen sie alle mit einer »5« enden.

Illustration

0.1000000000000000055511151231257827021181583404541015625

+ 0.200000000000000011102230246251565404236316680908203125

= 0.3000000000000000444089209850062616169452667236328125

- 0.299999999999999988897769753748434595763683319091796875

= 0.000000000000000055511151231257827021181583404541015625

Verhältnis zum Vorzeichenwechsel *

Der Vorzeichenwechsel »-65« kann auch als Abkürzung für »0 - 65« interpretiert werden.

Literale mit einem Operatorzeichen *

Das Literal »2e+03« ist keine Summe, sondern bedeutet „2·10³“. Um Summen deutlich von solchen Literalen mit einem inneren Pluszeichen oder einem inneren Minuszeichen zu unterscheiden, bietet es sich an, die binären Operatoren »+« und »-« mit einem umgebenden Leerzeichen zu verwenden.

Prioritäten

Die bisher vorgestellten Operatoren haben Prioritäten gemäß der folgenden Tabelle: Ein weiter oben stehender Operator hat eine höhere Priorität.

Eigenschaften

A P A (A = Aritaet, P = Position, A = Assoziativitaet)

() 1 Z Eingeklammerter Ausdruck
+ - 1 P Unaere vorangestellte Operatoren (Vorzeichen)
* / 2 I L "Punktrechnung": Multiplikation, Division
+ - 2 I L "Strichrechnung": Addition, Subtraktion

Man sagt ja auch: „Punktrechnung geht vor Strichrechnung.“ – „Punktrechnung“ umfaßt die Operatoren mit Punkten (die Multiplikation ‹ · › und die Division ‹ : ›) und „Strichrechnung“ die Operatoren mit Strichen (die Addition ‹ + › und die Subtraktion ‹  ›).

Operatoren als lexikalische Einheiten

Jeder Operator ist eine lexikalische Einheit für sich, nur der Zirkumfixoperator »()« besteht aus zwei  lexikalischen Einheiten (jede Klammer ist jeweils eine lexikalische Einheit für sich.)

Operatorausdrücke als Ausdrücke

Die in dieser Lektion vorgestellten Operatorausdrücke sind alle Ausdrücke, deren Auswertung den jeweils beschriebenen Wert ergibt.

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram722468 stefan_ram:722468 Die Subtraktion in C++, Minus, binärer Minusoperator Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd722468, slrprddef722468, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/subtraktion_c++_de