Die Division »…/…« in C♯
Einführendes Beispiel
Die Division wird mit einem Schrägstrich »/« geschrieben (in der Mathematik ist auch ‹÷› üblich). Der Schrägstrich »/« sollte nicht mit dem inversen Schrägstrich »\« verwechselt werden!
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 70/10 ); }}global::System.Console.Out
7
Syntax
- Neue, erweiterte Syntax
Ausdruck
.----------.
---.----------->| Literal |---------------------------.---->
| '----------' |
| .-. .----------. |
'--->( - )-->| Ausdruck |---------------------------'
| '-' '----------' |
| .-. .----------. |
'--->( + )-->| Ausdruck |---------------------------'
| '-' '----------' |
| .-. .----------. .-. |
'--->( ( )-->| Ausdruck |-->( ) )-------------------'
| '-' '----------' '-' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( / )-->| Ausdruck |----'
'----------' '-' '----------'
Wir hatte einen Operator bisher als ein Zeichen kennengelernt, das mit einem Operanden zusammen geschrieben wird. Nun erweitern wir den Begriff dahingehend, daß ein Operator auch zwei Operanden haben kann. Der Divisionsoperator wird zwischen seine beiden Operanden geschrieben.
Sind D und d zwei Ausdrücke, so ist D /d wieder ein Ausdruck, der Quotient von D und d. Dabei wird D auch Dividend und d Divisor (diˈviːzoːʌ̯) genannt: „Dividend/Divisor“. (Diese vereinfachte Syntax bringt die Assoziativität der Division nicht richtig zum Ausdruck. Diese wird daher weiter unten separat erklärt.) Dieser Operator hat zwei Operandenausdrücke (einen linken und einen rechten). Er wird daher binär genannt, während die zuvor vorgestellten Operatoren unär waren (sie hatten nur einen Operandenausdruck). Weil dieser Operator zwischen seinen Operandenausdrücken steht, wird er auch als ein Infixoperator bezeichnet.
Typanforderungen
Der Dividend und der Divisor müssen beide jeweils numerisch sein.
Verwendung mit gleichen Typen
Dieser Operator kann mit double - und int -Werten verwendet werden. Zunächst sollten beide Operandenausdrücke »double« oder beide »int« sein. »double«/»double« verhält sich dabei anders als »int«/»int«.
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1.0/2.0 ); }}global::System.Console.Out
0.5
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1/2 ); }}global::System.Console.Out
0
Sind beide Operandenausdrücke int, bedeutet der Operator die „ganzzahlige Division“. Dabei werden die Nachkommastellen des Ergebnisses abgeschnitten. (Den Fall negativer Werte wollen wir hier zur Vereinfachung nicht weiter betrachten.)
Der Operator ist polymorph, da er mit verschiedenen Typen verwendet werden kann und dabei für verschiedene Divisionsprogramme steht. (Die Polymorphie ist eigentlich die Eigenschaft seiner Operandenausdrücke von verschiedenem Typ sein zu können, also beide int oder beide double.) Der Operator hat für jeden Typ dieselbe Bedeutung, nämlich „Division“ (semantische Konsistenz), jedoch wird diese für int /int anders umgesetzt (interpretiert) als für double /double.
Dieser Operator verdeutlicht, daß ein Typ eines Ausdrucks ein Etikett ist, welches einem Ausdruck beigegeben wird, um die für einen Operator zu wählende Operation festzulegen.
Der Typ des gesamten Ausdrucks und seines Wertes ergibt sich gemäß der folgenden Tabelle.
- Typ der Division
- int /int = int
- double /double = double
Verwendung mit verschiedenen Typen
Bei einer Mischung int /double oder double /int wird der int -Wert in den ihn entsprechenden double -Wert uminterpretiert (aus dem int -Wert »2« wird beispielsweise der double -Wert »2.0«.)
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1.0/2 ); }}global::System.Console.Out
0.5
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1/2.0 ); }}global::System.Console.Out
0.5
- Typ der Division
- int /double → double /double = double
- double /int → double /double = double
Typ
Ist der Typ des einen Operanden »double«, so wird der Wert des anderen Operand nach »double« gewandelt und der Typ des gesamten Ausdrucks hat den Typ »double«. Sonst hat der gesamte Ausdruck den Typ »int«. (Diese Beschreibung berücksichtigt nur die bisher vorgestellten Typen.)
Typregeln
- mindestens ein double -Operand → Ergebnis double
nur int -Operanden → Ergebnis int
Typregeln (andere Formulierung)
- double /double → double
double /int → double
int /double → double
int /int → int
Man kann auch sagen, daß der Typ »double« „größer“ als der Typ »int« sei, weil er alle Wert des Typs »int« und noch weitere Werte umfaßt. Damit kann man dann sagen, daß bei der Verknüpfung zweier Werte der Wert des kleineren Typs zum Wert des größeren Typs erweitert wird und der Typ des Ergebnisses einer Division das Maximum der Typen der Operanden ist.
Wert
Bei der Auswertung einer Division werden beide Operanden ausgewertet. Der Wert einer double /double -Division ist (bis auf meist kleine Abweichungen) der normale Quotient der beiden Werte, der Wert einer int /int -Division jedoch nur der ganzzahlige Anteil dieses Quotienten. Der ganzzahlige Anteil einer Division ‹x ∕y › wird in der Mathematik auch als ‹x ∖ y › geschrieben.
Assoziativität
Die Division ist linksassoziativ, das heißt in »12/3/2« ist »12/3« ein Ausdruck, aber nicht »3/2«. »12/3/2« bedeutet also »(12/3)/2« – es wird von links beginnend zusammengefaßt.
In »12/3/2« ist der Teil »12/3« ein Teilausdruck, nicht jedoch »3/2«, da die »3« mit »12/« zusammengefaßt wird und nicht mit »/2«. Einen Teilausdruck, wie »12/3« in »12/3/2« kann man isoliert betrachten, wenn man seinen Wert bestimmen will.
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 12/3/2 ); }}global::System.Console.Out
2
Operationen
Unter einer Operation verstehen wir einen Rechenschritt, im Sinne eines direkt zu einem bestimmten Operator gehörenden Teil der Auswertung eines Ausdrucks. Eine Operation findet also während der Ausführung eines Programms statt. Beim Operator »/« ist die Operation beispielsweise eine Division.
Die Operation zu einem Operator umfaßt nicht die Auswertung von Operanden dieses Operators. Sie erfolgt vielmehr, nachdem alle Operanden bereits ausgewertet wurden.
Bei der Berechnung von »12 / 3 / 2« werden beispielsweise die Operationen »12 / 3« und »4 / 2« ausgeführt. Wir haben hierbei die Operationen durch eine Operatorausdruck angegeben, in dem alle Operanden Literale sind.
In den folgenden Darstellungen von Operationen zeigen wir den vollständigen Ausdruck vor und nach dem Ersetzen eines Operatorausdrucks durch ein gleichwertiges Literal. Der ersetzte Ausdruck wird dabei durch eine über ihm stehenden Linie markiert. (Dieses Ersetzen eines Operatorausdrucks durch ein Literal mit genauem oder näherungsweise gleichem Wert nennen wir eine Reduktion. Eine Reduktion ist eine Form der Veranschaulichung einer Operation.)
Operationen bei der Auswertung von »12 / 3 / 2«:
12 / 3
______
12 / 3 / 2 →
4 / 24 / 2
_____
4 / 2 →
2
Der Ausdruck »12 / 3 / 2« wird also mit zwei Operationen ausgewertet. Zuerst wird die linke Division ausgeführt, weil der Operator linksassoziativ ist, dann wird die rechte Division vollzogen.
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( ( 12/3 )/2 ); }}global::System.Console.Out
2
Möchte man »12« durch »3/2« teilen, so muß man dies als »12/( 3/2 )« schreiben.
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 12/( 3 / 2 )); }}global::System.Console.Out
12
Operationen bei der Auswertung von »12 /( 3/2 )«:
3 / 2
_______
12 /( 3/2 ) →
12 / 112 / 1
______
12 / 1 →
12
Im Falle des Ausdrucks »12 /( 3/2 )« wird nun der rechte Quotient als Ausdruck ausgewertet, weil er in runde Klammern eingeschlossen wurde.
Priorität
Der Vorzeichenwechsel hat eine höhere Priorität als die Division. Dies heißt, daß der Vorzeichenwechseloperator in »-3/2« sich nur auf die »3« bezieht und nicht etwas auf den gesamten Bruch.
Bei der Auswertung von »-3/2« wird zuerst der Vorzeichenwechsel und dann die Division ausgeführt.
Bei der Auswertung von »-( 3/2 )« wird zuerst die Division und dann der Vorzeichenwechsel ausgeführt.
Da es weiteren Verlauf des Kurses nicht wichtig ist, die Auswertung von Vorzeichenwechseln ausdrücklich darzustellen, verzichten wir zur Vereinfachung darauf, wenn wir Operationen einer Auswertung angeben, so wie wir auch auf die Darstellung von Operationen zu Ausdruckklammern verzichten. Wir interpretieren beispielsweise die Auswertung von »-( 3/2 )« als eine Division mit dem Ergebnis »-1.5«, ohne die Klammern und das Vorzeichen als eigene Operationen zu würdigen.
In der folgenden Tabelle zur Priorität von Operatoren finden sich Operatoren mit höherer Priorität weiter oben
- Priorität der bisher behandelten Operatoren
() Eingeklammerter Ausdruck
+ - Unaere vorangestellte Operatoren
/ Division
Kontextunabhängigkeit
Der Wert von »1/2/3.0« ist »0.0«.
Zunächst einmal ergibt der erste Teilausdruck »1/2« den Wert »0« vom Typ »int«, da hier beide Operanden den Typ »int« haben.
Anschließend wird der Wert »0« vom Typ »int« durch den Wert »3.0« vom Typ »double« geteilt. Bei dieser – zweiten – Division werden nun Nachkommastellen berücksichtigt, was aber nichts daran ändert, daß die Nachkommastellen bei der ersten Division verworfen wurden.
Bei der Auswertung des ersten Ausdrucks »1/2« wurde nicht berücksichtigt, daß dieser später mit einem double-Operanden kombiniert wird. Das ist ein allgemeines Grundprinzip:
Bei der Auswertung eines Teilausdrucks wird der enthaltende Ausdruck nicht berücksichtigt.
Der Wert und der Typ eines Operatorausdruckswerden also nur durch den Operator und seine Operanden bestimmt und nicht durch den Ort, an dem der Ausdruck verwendet wird.
»decimal«
Bei Divisionen darf auch der Typ »decimal« verwendet, aber nicht mit dem Typ »double« kombiniert werden.
Typregeln
- decimal /decimal → decimal
decimal /int → decimal
int /decimal → decimal Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1.0000000000m / 8.0000000000m ); }}global::System.Console.Out
0.125
Die Skalierung des Ergebnisses ergibt sich durch Abschneiden aller finalen Nullen nach dem Decimaltrennzeichen, sie wird also nicht durch die Skalierung der Operanden bestimmt. Dies kann verwendet werden, um solche Nullen zu entfernen.
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 123.0000000000m / 1 ); }}global::System.Console.Out
123
Innere Ausdrücke
Ein innerer Ausdruck, der innerhalb eines $-Literals in geschweiften Klammern steht, darf auch ein Operatorausdruck sein.
Innere Ausdrücke erlauben es, die Ergebnisse von Berechnungen auf einfache Weise zu beschriften.
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( $"1/7.0 = {1/7.0}." ); }}Protokoll
1/7.0 = 0.142857142857143.
Hinweis für den Dozenten ► Eventuell wird »CultureInfo.CurrentCulture« verwendet, um die Formatierung von Dezimaltrennzeichen festzulegen.
Übungsfragen
? Ausdrücke
Welche Typen und Werte haben die folgenden Ausdrücke jeweils?
- A »1 / 2 / 2«
- B »1 /( 2 / 4.0 )«
- C »1 / 2 / 4.0«
? Verständnis von Fachbegriffen *
Zu einem (hypothetischen) binären Infixoperator »∘« wird erklärt: „Der Wert eines Ausdrucks, der aus dem Operator »∘« sowie einem zu diesem Operator gehörenden linken und rechten Operanden besteht, ist der Wert des linken Operanden.“.
Welchen Wert hat demnach »4∘7«?
Welchen Wert hat »4∘2∘7«?
(Kürzere Formulierung der Erklärung: „Der Wert des Operator »∘« ist der Wert seines linken Operanden.“.)
? Verständnis von Fachbegriffen *
Angenommen die Division »/« wäre nicht linksassoziativ, sondern rechtsassoziativ. Welchen Wert hätte dann der Ausdruck »12/4/2«?
? Operanden und Operatoren *
Wie viele Operanden hat der erste Divisionsoperator »/« in dem Ausdruck »8/4/2«? Was sind diese Operanden? (Nicht die Werte der Operanden sind hier gesucht, sondern die Operandenausdrücke.)
Wie viele Operanden hat der zweite Divisionsoperator »/« in dem Ausdruck »8/4/2«? Was sind diese Operanden? (Nicht die Werte der Operanden sind hier gesucht, sondern die Operandenausdrücke.)
Welcher der beiden Divisionsoperatoren »/« wird bei der Ermittlung des Wertes des Ausdrucks »8/4/2« als letzter ausgeführt?
Beispiel Die ganzzahligen Division *
- Abbildung von 47 Flaschen
o o o o o o o o o o o o o o o o o o o o o o o o
o o o o o o o o o o o o o o o o o o o o o o o- Abbildung von leeren Kartons
| | | | | | | | | | | | | | |
-|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|-
| | | | | | | | | | | | | | |- Abbildung elf gefüllter Kartons
o|o o|o o|o o|o o|o o|o o|o o|o o|o o|o o|o o o
-|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|-
o|o o|o o|o o|o o|o o|o o|o o|o o|o o|o o|o o
| | | |
-|- -|- -|- -|-
| | | |
47 Flaschen sollen in Kartons verpackt werden, die jeweils vier Flaschen aufnehmen können. Alle Kartons müssen immer vollständig mit jeweils vier Flaschen gefüllt werden, es ist also nicht erlaubt, daß ein Karton nur teilweise gefüllt wird. Wie viele Kartons können gefüllt werden?
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 47 / 4 ); }}global::System.Console.Out
11
Es können elf Kartons gefüllt werden.