Operatorverhalten

In diesem Abschnitt wird das Verhalten der verschiedenen M-Operatoren definiert.

Operatorrangfolge

Wenn ein Ausdruck mehrere Operatoren enthält, steuert die Rangfolge der Operatoren die Reihenfolge, in der die einzelnen Operatoren ausgewertet werden. Beispielsweise wird der Ausdruck x + y * z als x + (y * z) ausgewertet, da der *-Operator eine höhere Rangfolge aufweist als der binäre +-Operator. Die Rangfolge eines Operators wird durch die Definition der zugehörigen Grammatikproduktion festgelegt. Beispielsweise besteht ein additive-expression-Ausdruck aus einer Folge von multiplicative-expression-Ausdrücken, die durch die Operatoren + bzw. - voneinander getrennt sind. Dadurch haben die Operatoren + und - eine niedrigere Rangfolge als die Operatoren * und /.

Die Produktion parenthesized-expression (Ausdruck in Klammern) kann zum Ändern der Standardrangfolge verwendet werden.

Ausdruck in Klammern:
      (expression)

Beispiel:

1 + 2 * 3       // 7 
(1 + 2) * 3     // 9

In der folgenden Tabelle sind die M-Operatoren zusammengefasst, wobei die Operatorkategorien von der höchsten zur niedrigsten Rangfolge angegeben sind. Operatoren in derselben Kategorie haben die gleiche Rangfolge.

Kategorie Ausdruck BESCHREIBUNG
Primär i
@i
Bezeichnerausdruck
(x) Ausdruck in Klammern
x[i] Lookup
x{y} Elementzugriff
x(...) Funktionsaufruf
{x, y, ...} Listeninitialisierung
[ i = x, ... ] Datensatzinitialisierung
... Nicht implementiert
Unäroperatoren +x Identity
-x Negation
notx Logische Negation
Metadaten xmetay Metadatenzuordnung
Multiplikativ x * y Multiplikation
x / y Division
Additiv x + y Addition
x - y Subtraktion
Relational x< y Kleiner als
x > y Größer als
x<= y Kleiner als oder gleich
x >= y Größer als oder gleich
Gleichheit x = y Gleich
x<> y Ungleich
Typassertion xasy Kompatibler „nullable-primitive“-Typ oder Fehler
Typübereinstimmung xisy Test, ob kompatibler „nullable-primitive“-Typ oder Fehler
Logisches AND xandy Verkürzte Konjunktion
Logisches OR xory Verkürzte Disjunktion
Coalesce x??y NULL-Sammeloperator

Operatoren und Metadaten

Jeder Wert verfügt über einen zugeordneten Datensatzwert, der zusätzliche Informationen über den Wert enthalten kann. Dieser Datensatz wird als Metadatensatz für einen Wert bezeichnet. Ein Metadatensatz kann einem beliebigen Wert zugeordnet werden, auch dem Wert null. Das Ergebnis einer solchen Zuordnung ist ein neuer Wert mit den angegebenen Metadaten.

Bei einem Metadatensatz handelt es sich einfach um einen regulären Datensatz. Er kann beliebige Felder und Werte enthalten, die auch ein regulärer Datensatz enthalten kann, und weist selbst einen Metadatensatz auf. Die Zuordnung eines Metadatensatzes zu einem Wert ist „nicht intrusiv“. Dadurch ändert sich nichts am Verhalten des Werts in Auswertungen – außer bei Auswertungen, die Metadatensätze explizit prüfen.

Jeder Wert verfügt über einen Standardmetadatensatz, auch dann, wenn keiner angegeben wurde. Der Standardmetadatensatz ist leer. In den folgenden Beispielen wird der Zugriff auf den Metadatensatz eines Textwerts mithilfe der Standardbibliotheksfunktion Value.Metadata veranschaulicht:

Value.Metadata( "Mozart" )   // []

Metadatensätze bleiben im Allgemeinen nicht erhalten, wenn ein Wert mit einem Operator oder einer Funktion verwendet wird, um einen neuen Wert zu erzeugen. Wenn beispielsweise zwei Textwerte mit dem Operator & verkettet werden, sind die Metadaten des resultierenden Textwerts ein leerer Datensatz []. Die folgenden Ausdrücke sind äquivalent:

"Amadeus " & ("Mozart" meta [ Rating = 5 ])  
"Amadeus " & "Mozart"

Mit den Standardbibliotheksfunktionen Value.RemoveMetadata und Value.ReplaceMetadata können alle Metadaten aus einem Wert entfernt und die Metadaten eines Werts ersetzt werden (statt Metadaten mit möglicherweise vorhandenen Metadaten zusammenzuführen).

Der einzige Operator, der Ergebnisse zurückgibt, die Metadaten enthalten, ist der Meta-Operator.

Strukturell rekursive Operatoren

Werte können zyklisch sein. Beispiel:

let l = {0, @l} in l
// {0, {0, {0, ... }}}
[A={B}, B={A}]
// [A = {{ ... }}, B = {{ ... }}]

M verarbeitet zyklische Werte, indem die Erstellung von Datensätzen, Listen und Tabellen verzögert beibehalten wird. Der Versuch, einen zyklischen Wert zu erstellen, der nicht von eingeworfenen, verzögert strukturierten Werten profitiert, ergibt einen Fehler:

[A=B, B=A] 
// [A = Error.Record("Expression.Error", 
//         "A cyclic reference was encountered during evaluation"), 
//  B = Error.Record("Expression.Error", 
//         "A cyclic reference was encountered during evaluation"), 
// ]

Einige Operatoren in M werden durch strukturelle Rekursion definiert. Beispielsweise wird die Gleichheit von Datensätzen und Listen durch die gemeinsame Gleichheit der entsprechenden Datensatzfelder bzw. Elementlisten definiert.

Bei nicht zyklischen Werten führt das Anwenden der strukturellen Rekursion zu einer begrenzten Erweiterung des Werts: freigegebene, geschachtelte Werte werden wiederholt durchlaufen, der Rekursionsprozess wird jedoch immer beendet.

Ein zyklischer Wert weist eine unbegrenzte Erweiterung auf, wenn eine strukturelle Rekursion angewendet wird. In der Semantik von M werden solche unbegrenzten Erweiterungen nicht besonders berücksichtigt: Beim Versuch, zyklische Werte auf Gleichheit zu prüfen, reichen die Ressourcen beispielsweise nicht aus und der Vorgang wird mit einer Ausnahme beendet.

Auswahl- und Projektionsoperatoren

Mithilfe der Auswahl- und Projektionsoperatoren können Daten aus Listen- und Datensatzwerten extrahiert werden.

Elementzugriff

Ein Wert kann in einer Liste oder Tabelle anhand seiner nullbasierten Position innerhalb dieser Liste oder Tabelle mithilfe eines item-access-expression-Ausdrucks ausgewählt werden.

item-access-expression:
      item-selection
      optional-item-selection
item-selection:
      primary-expression
{item-selector}
optional-item-selection:
      primary-expression
{item-selector} ?
item-selector:
      expression

Die item-access-expressionx{y} (der Elementzugriffsausdruck) gibt Folgendes zurück:

  • Bei einer Liste x und einer Zahl y, das Element von Liste x an Position y. Es wird davon ausgegangen, dass der Ordinalindex beim ersten Element einer Liste 0 (Null) ist. Wenn die angeforderte Position in der Liste nicht vorhanden ist, wird ein Fehler ausgelöst.

  • Bei einer Tabelle x und einer Zahl y, die Zeile der Tabelle x an Position y. Es wird davon ausgegangen, dass der Ordinalindex bei der ersten Zeile einer Tabelle 0 (Null) ist. Wenn die angeforderte Position in der Tabelle nicht vorhanden ist, wird ein Fehler ausgelöst.

  • Bei einer Tabelle x und einem Datensatz y, die Zeile der Tabelle x, die mit den Feldwerten von Datensatz y für Felder mit Feldnamen übereinstimmt, die mit den entsprechenden „table-column“-Namen übereinstimmen. Wenn in der Tabelle keine eindeutige, übereinstimmende Zeile vorhanden ist, wird ein Fehler ausgelöst.

Beispiel:

{"a","b","c"}{0}                        // "a" 
{1, [A=2], 3}{1}                        // [A=2] 
{true, false}{2}                        // error 
#table({"A","B"},{{0,1},{2,1}}){0}      // [A=0,B=1] 
#table({"A","B"},{{0,1},{2,1}}){[A=2]}  // [A=2,B=1]  
#table({"A","B"},{{0,1},{2,1}}){[B=3]}  // error 
#table({"A","B"},{{0,1},{2,1}}){[B=1]}  // error

Der item-access-expression-Ausdruck unterstützt auch die Form x{y}?, die null zurückgibt, wenn die Position (oder die Übereinstimmung) y in der Liste oder Tabelle x nicht vorhanden ist. Wenn für y mehrere Übereinstimmungen vorhanden sind, wird ein Fehler ausgelöst.

Beispiel:

{"a","b","c"}{0}?                       // "a" 
{1, [A=2], 3}{1}?                       // [A=2] 
{true, false}{2}?                       // null 
#table({"A","B"},{{0,1},{2,1}}){0}?     // [A=0,B=1] 
#table({"A","B"},{{0,1},{2,1}}){[A=2]}? // [A=2,B=1]  
#table({"A","B"},{{0,1},{2,1}}){[B=3]}? // null 
#table({"A","B"},{{0,1},{2,1}}){[B=1]}? // error

Mit Elementzugriff wird nur die Auswertung von den Listen- oder Tabellenelementen erzwungen, auf die zugegriffen wird. Beispiel:

{ error "a", 1, error "c"}{1}  // 1 
{ error "a", error "b"}{1}     // error "b"

Folgendes gilt, wenn der Elementzugriffsoperator x{y} ausgewertet wird:

  • Fehler, die während der Auswertung der Ausdrücke x und y ausgelöst werden, werden weitergegeben.

  • Der Ausdruck x erzeugt einen Listen- oder Tabellenwert.

  • Der Ausdruck y erzeugt einen Zahlenwert oder einen Datensatzwert, falls x einen Tabellenwert erzeugt.

  • Wenn y einen Zahlenwert erzeugt und der Wert y negativ ist, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

  • Wenn y einen Zahlenwert erzeugt und der Wert y größer oder gleich der Anzahl von x ist, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst, es sei denn, die optionale Operatorform x{y}? wird verwendet. In diesem Fall wird der Wert null zurückgegeben.

  • Wenn x einen Tabellenwert und y einen Datensatzwert erzeugt und in x keine Übereinstimmungen für y vorhanden sind, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst, es sei denn, die optionale Operatorform x{y}? wird verwendet. In diesem Fall wird null zurückgegeben.

  • Wenn x einen Tabellenwert und y einen Datensatzwert erzeugt und in xmehrere Übereinstimmungen für y vorhanden sind, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

Während der Elementauswahl werden in x nur Elemente an Position y ausgewertet. (Bei Streaminglisten oder -tabellen werden die Elemente oder Zeilen davor an Position y übersprungen, was je nach Quelle der Liste oder Tabelle dazu führen kann, dass sie ausgewertet werden.)

Feldzugriff

Der field-access-expression-Ausdruck wird verwendet, um einen Wert in einem Datensatz auszuwählen oder einen Datensatz bzw. eine Tabelle auf einen Datensatz bzw. eine Tabelle mit weniger Feldern bzw. Spalten zu projizieren.

field-access-expression:
      field-selection
      implicit-target-field-selection
      Projektion (projection)
      implicit-target-projection
field-selection:
      primary-expression field-selector
field-selector:
      required-field-selector
      optional-field-selector
required-field-selector:

      [field-name]
optionaler Feldselektor:
      [field-name] ?
field-name:
      generalized-identifier
      quoted-identifier
implicit-target-field-selection:
      field-selector
projection:
      primary-expression required-projection
      primary-expression optional-projection
required-projection:

      [required-selector-list]
optionale Projektion:
      [required-selector-list] ?
required-selector-list:
      required-field-selector
      required-selector-list
,required-field-selector
implicit-target-projection:
      required-projection
      optional-projection

Die einfachste Form des Feldzugriffs ist die Auswahl erforderlicher Felder. Dabei wird der Operator x[y] verwendet, um in einem Datensatz anhand des Feldnamens nach einem Feld zu suchen. Wenn das Feld y in x nicht vorhanden ist, wird ein Fehler ausgelöst. Die Form x[y]? wird verwendet, um eine optionale Feldauswahl auszuführen. Dabei wird null zurückgegeben, wenn das angeforderte Feld im Datensatz nicht vorhanden ist.

Beispiel:

[A=1,B=2][B]       // 2 
[A=1,B=2][C]       // error 
[A=1,B=2][C]?      // null

Der gemeinsame Zugriff mehrerer Felder wird von den Operatoren für erforderliche Datensatzprojektionen und optionale Datensatzprojektionen unterstützt. Der Operator x[[y1],[y2],...] projiziert den Datensatz in einen neuen Datensatz mit weniger Feldern (ausgewählt durch y1, y2, ...). Wenn kein ausgewähltes Feld vorhanden ist, wird ein Fehler ausgelöst. Der Operator x[[y1],[y2],...] projiziert den Datensatz in einen neuen Datensatz mit den Feldern, die durch y1, y2, ... ausgewählt wurden. Wenn ein Feld fehlt, wird stattdessen null verwendet. Beispiel:

[A=1,B=2][[B]]           // [B=2] 
[A=1,B=2][[C]]           // error 
[A=1,B=2][[B],[C]]?      // [B=2,C=null]

Die Formen [y] und [y]? werden als Kurzverweise auf den Bezeichner _ (Unterstrich) unterstützt. Die folgenden beiden Ausdrücke sind äquivalent:

[A]                 
_[A]

Im folgenden Beispiel wird die Kurzform des Feldzugriffs veranschaulicht:

let _ = [A=1,B=2] in [A] //1

Die Formen [[y1],[y2],...] und [[y1],[y2],...]? werden ebenfalls als Kurzformen unterstützt. Und die beiden Ausdrücke sind ebenfalls äquivalent:

[[A],[B]]                 
_[[A],[B]]

Die Kurzform ist in Kombination mit der Kurzform each besonders nützlich, die eine Möglichkeit darstellt, einen Parameter mit dem Namen _ einzuführen. (Ausführliche Informationen finden Sie unter Vereinfachten Deklarationen.) Zusammen vereinfachen die beiden Kurzformen gängige funktionale Ausdrücke höherer Ordnung:

List.Select( {[a=1, b=1], [a=2, b=4]}, each [a] = [b]) 
// {[a=1, b=1]}

Der obige Ausdruck entspricht der folgenden kryptischer aussehenden Langform:

List.Select( {[a=1, b=1], [a=2, b=4]}, (_) => _[a] = _[b]) 
// {[a=1, b=1]}

Mit Feldzugriff wird nur die Auswertung von den Feldern erzwungen, auf die zugegriffen wird. Beispiel:

[A=error "a", B=1, C=error "c"][B]  // 1 
[A=error "a", B=error "b"][B]       // error "b"

Folgendes gilt, wenn der Feldzugriffsoperator x[y], x[y]?, x[[y]] oder x[[y]]? ausgewertet wird:

  • Fehler, die während der Auswertung des Ausdrucks x ausgelöst werden, werden weitergegeben.

  • Fehler, die beim Auswerten von Feld y ausgelöst werden, werden dem Feld ypermanent zugeordnet und dann weitergegeben. Bei jedem zukünftigen Zugriff auf Feld y wird der identische Fehler ausgegeben.

  • Der Ausdruck x erzeugt einen Datensatz- oder Tabellenwert, oder es wird ein Fehler ausgelöst.

  • Wenn der Bezeichner y ein Feld benennt, das in x nicht vorhanden ist, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst, es sei denn, die optionale Operatorform ...? wird verwendet. In diesem Fall wird der Wert null zurückgegeben.

Beim Feldzugriff werden nur die durch y benannten Felder x ausgewertet.

Metadatenoperator

Der Metadatensatz für einen Wert wird mit dem Meta-Operator (x meta y) geändert.

metadata-expression:
      unary-expression
      unary-expression
metaunary-expression

Im folgenden Beispiel wird ein Textwert mit einem Metadatensatz erstellt, der den Operator meta verwendet. Anschließend wird mithilfe von Value.Metadata auf den Metadatensatz des resultierenden Werts zugegriffen:

Value.Metadata( "Mozart" meta [ Rating = 5 ] ) 
// [Rating = 5 ]
Value.Metadata( "Mozart" meta [ Rating = 5 ] )[Rating] 
// 5

Folgendes gilt, wenn der metadatenkombinierende Operator x meta y angewendet wird:

  • Fehler, die beim Auswerten der Ausdrücke x und y ausgelöst werden, werden weitergegeben.

  • Der Ausdruck y muss ein Datensatz sein, da andernfalls ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst wird.

  • Der resultierende Metadatensatz ist der mit y zusammengeführte Metadatensatz von x. (Informationen zur Semantik der Datensatzzusammenführung finden Sie unter Datensatzzusammenführung.)

  • Der resultierende Wert ist der Wert aus dem Ausdruck x ohne Metadaten, jedoch mit dem neu berechneten Metadatensatz.

Mit den Standardbibliotheksfunktionen Value.RemoveMetadata und Value.ReplaceMetadata können alle Metadaten aus einem Wert entfernt und die Metadaten eines Werts ersetzt werden (statt Metadaten mit möglicherweise vorhandenen Metadaten zusammenzuführen). Die folgenden Ausdrücke sind äquivalent:

x meta y  
Value.ReplaceMetadata(x, Value.Metadata(x) & y) 
Value.RemoveMetadata(x) meta (Value.Metadata(x) & y)

Gleichheitsoperatoren

Der Gleichheitsoperator= wird verwendet, um zu ermitteln, ob zwei Werte gleich sind. Der Ungleichheitsoperator<> wird verwendet, um zu ermitteln, ob zwei Werte ungleich sind.

equality-expression:
      relational-expression
      relational-expression
=equality-expression
      relational-expression
<>equality-expression

Beispiel:

1 = 1            // true 
1 = 2            // false 
1 <> 1           // false 
1 <> 2           // true 
null = true      // false 
null = null      // true

Metadaten sind nicht Teil der Prüfung auf Gleichheit oder Ungleichheit. Beispiel:

(1 meta [ a = 1 ]) = (1 meta [ a = 2 ]) // true 
(1 meta [ a = 1 ]) = 1                  // true

Folgendes gilt, wenn die Gleichheitsoperatoren x = y und x <> y angewendet werden:

  • Fehler, die beim Auswerten der Ausdrücke x und y ausgelöst werden, werden weitergegeben.

  • Der Operator = ergibt true, wenn die Werte gleich sind, andernfalls ergibt er false.

  • Der Operator <> ergibt false, wenn die Werte gleich sind, andernfalls ergibt er true.

  • Metadatensätze werden bei der Überprüfung nicht berücksichtigt.

  • Wenn Werte, die durch Auswerten der Ausdrücke x und y erzeugt werden, nicht der gleiche Art von Wert entsprechen, sind die Werte nicht gleich.

  • Wenn die Werte, die durch Auswerten der Ausdrücke x und y erzeugt werden, der gleichen Art von Wert entsprechen, gibt es bestimmte Regeln zur Ermittlung, ob sie gleich sind (die im Folgenden beschrieben werden).

  • Folgendes gilt immer:

    (x = y) = not (x <> y)

Die Gleichheitsoperatoren sind für die folgenden Typen definiert:

  • Der Wert null ist nur mit sich selbst identisch.
    null = null    // true 
    null = true    // false 
    null = false   // false
  • Die logischen Werte true und false sind nur mit sich selbst identisch. Beispiel:
    true = true      // true 
    false = false    // true 
    true = false     // false 
    true = 1         // false
  • Zahlen werden mit der angegebenen Genauigkeit verglichen:

    • Wenn eine der beiden Zahlen #nan ist, sind die Zahlen nicht identisch.

    • Wenn keine Zahl #nan ist, werden die Zahlen bitweise mit dem numerischen Wert verglichen.

    • #nan ist der einzige Wert, der nicht mit sich selbst identisch ist.

      Beispiel:

        1 = 1,              // true 
        1.0 = 1             // true 
        2 = 1               // false 
        #nan = #nan         // false 
        #nan <> #nan        // true
  • Zwei duration-Werte sind gleich, wenn sie die gleiche Anzahl von 100-Nanosekunden-Ticks darstellen.

  • Zwei time-Werte sind gleich, wenn die Größen ihrer Teile (Stunde, Minute, Sekunde) gleich sind.

  • Zwei date-Werte sind gleich, wenn die Größen ihrer Teile (Jahr, Monat, Tag) gleich sind.

  • Zwei datetime-Werte sind gleich, wenn die Größen ihrer Teile (Jahr, Monat, Tag, Stunde, Minute, Sekunde) gleich sind.

  • Zwei datetimezone-Werte sind gleich, wenn die entsprechenden datetime-Werte in koordinierter Weltzeit gleich sind. Der entsprechende datetime-Wert in koordinierter Weltzeit ergibt sich, indem die Stunden-/Minutenabweichung von der datetime-Komponente des datetimezone-Werts subtrahiert wird.

  • Zwei Textwerte sind gleich, wenn ein kulturunabhängiger Ordinalvergleich, bei dem die Groß-/Kleinschreibung beachtet wird, ergibt, dass die Werte an den entsprechenden Positionen dieselbe Länge und dieselbe Anzahl von Zeichen aufweisen.

  • Zwei Listenwerte sind gleich, wenn Folgendes zutrifft:

    • Beide Listen enthalten dieselbe Anzahl von Elementen.

    • Die Werte aller Elemente mit derselben Position in den Listen sind gleich. Das bedeutet, dass die Listen nicht nur die gleichen Elemente enthalten müssen, sondern die Elemente darüber hinaus auch in derselben Reihenfolge vorliegen müssen.

      Beispiel:

        {1, 2} = {1, 2}     // true 
        {2, 1} = {1, 2}     // false 
        {1, 2, 3} = {1, 2}  // false
      
  • Zwei Datensätze sind gleich, wenn Folgendes zutrifft:

    • Die Anzahl der Feldeingaben ist gleich.

    • Jeder Feldname eines Datensatzes ist auch im anderen Datensatz vorhanden.

    • Der Wert der einzelnen Felder eines Datensatzes entspricht dem jeweils gleichnamigen Feld im anderen Datensatz.

      Beispiel:

        [ A = 1, B = 2 ] = [ A = 1, B = 2 ]        // true 
        [ B = 2, A = 1 ] = [ A = 1, B = 2 ]        // true 
        [ A = 1, B = 2, C = 3 ] = [ A = 1, B = 2 ] // false 
        [ A = 1 ] = [ A = 1, B = 2 ]               // false
      
  • Zwei Tabellen sind gleich, wenn Folgendes zutrifft:

    • Die Anzahl der Spalten ist gleich.

    • Jeder Spaltenname in einer Tabelle ist auch in der anderen Tabelle vorhanden.

    • Die Anzahl der Zeilen ist gleich.

    • Jede Zeile enthält in den entsprechenden Zellen die gleichen Werte.

      Beispiel:

        #table({"A","B"},{{1,2}}) = #table({"A","B"},{{1,2}}) // true 
        #table({"A","B"},{{1,2}}) = #table({"X","Y"},{{1,2}}) // false 
        #table({"A","B"},{{1,2}}) = #table({"B","A"},{{2,1}}) // true
      
  • Ein Funktionswert ist gleich sich selbst, entspricht jedoch möglicherweise auch einem anderen Funktionswert. Wenn zwei Funktionswerte als gleich gelten, verhalten sie sich beim Aufrufen identisch.

    Zwei gegebene Funktionswerte haben immer dieselbe Gleichheitsbeziehung.

  • Ein Typwert ist gleich sich selbst, entspricht jedoch möglicherweise auch einem anderen Typwert. Wenn zwei Typwerte als gleich gelten, verhalten sie sich identisch, wenn sie auf Übereinstimmungen abgefragt werden.

    Zwei gegebene Typwerte haben immer dieselbe Gleichheitsbeziehung.

Relationale Operatoren

Die Operatoren <, >, <= und >= werden als relationale Operatoren bezeichnet.

relational-expression:
      additive-expression
      additive-expression
<relational-expression
      additive-expression
>relational-expression
      additive-expression
<= _relational-expression
      additive-expression >=relational-expression

Diese Operatoren werden verwendet, um die relative Reihenfolgenbeziehung zwischen zwei Werten zu bestimmen, wie in der folgenden Tabelle dargestellt:

Vorgang Ergebnis
x < y true, wenn x kleiner ist als y, sonst false
x > y true, wenn x größer ist als y, sonst false
x <= y true, wenn x kleiner als oder gleich y, sonst false
x >= y true, wenn x größer als oder gleich y, sonst false

Beispiel:

0 <= 1            // true 
null < 1          // null 
null <= null      // null 
"ab" < "abc"      // true 
#nan >= #nan      // false  
#nan <= #nan      // false

Folgendes gilt beim Auswerten eines Ausdrucks, der die relationalen Operatoren enthält:

  • Fehler, die beim Auswerten der Operandenausdrücke x und y ausgelöst werden, werden weitergegeben.

  • Die Werte, die durch Auswerten der beiden Ausdrücke x und y erzeugt werden, müssen vom Typ „binary“, „date“, „datetime“, „datetimezone“, „duration“, „logical“, „number“, „null“, „text“ oder „time“ sein. Andernfalls wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

  • Der Werttyp beider Operanden muss identisch oder null sein. Andernfalls wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

  • Wenn einer der Operanden oder beide Operanden null sind, ist das Ergebnis der null-Wert.

  • Zwei Binärdateien werden Byte für Byte verglichen.

  • Zwei date-Werte werden miteinander verglichen, indem die Jahrteile verglichen werden. Sind diese gleich, werden die Monatsteile verglichen. Sind diese ebenfalls gleich, werden die Tagteile verglichen.

  • Zwei datetime-Werte werden miteinander verglichen, indem die Jahrteile verglichen werden. Sind diese gleich, werden die Monatsteile verglichen. Sind diese gleich, werden die Tagteile verglichen. Sind diese gleich, werden die Stundenteile verglichen. Sind diese gleich, werden die Minutenteile verglichen. Sind diese gleich, werden die Sekundenteile verglichen.

  • Zwei datetimezone-Werte werden miteinander verglichen, indem sie anhand der koordinierten Weltzeit durch Subtraktion von der Stunden- und Minutenabweichung normalisiert und anschließend mit ihren datetime-Komponenten verglichen werden.

  • Zwei duration-Werte werden anhand der Gesamtzahl der 100-Nanosekunden-Ticks verglichen, die sie darstellen.

  • Zwei logische Werte werden derart verglichen, dass true als höher als false betrachtet wird.

  • Zwei Zahlen x und y werden gemäß den Regeln der Norm IEEE 754 verglichen:

    • Wenn einer der beiden Operanden #nan ist, ist das Ergebnis für alle relationalen Operatoren false.

    • Wenn keiner der Operanden #nan ist, vergleichen die Operatoren die Werte der beiden Gleitkommaoperanden in Bezug auf die Reihenfolge -∞ < -max < ... < -min < -0.0 = +0.0 < +min < ... < +max < +∞, wobei „min“ und „max“ die kleinsten bzw. größten positiven endlichen Werte sind, die dargestellt werden können. Die M-Namen für „-∞“ und „+∞“ lauten -#infinity und #infinity.

      Wichtige Auswirkungen dieser Reihenfolge:

      • Negative und positive Nullen gelten als gleich.

      • Ein -#infinity-Wert gilt als kleiner als alle anderen Zahlenwerte, jedoch als gleich einem anderen -#infinity-Wert.

      • Ein #infinity-Wert gilt als größer als alle anderen Zahlenwerte, jedoch als gleich einem anderen #infinity-Wert.

  • Zwei Texte werden mit einem Zeichen-für-Zeichen-ordinal-, Groß-/Kleinschreibungs-, kulturunabhängigen Vergleich verglichen.

  • Zwei time-Werte werden miteinander verglichen, indem die Stundenteile verglichen werden. Sind diese gleich, werden die Minutenteile verglichen. Sind diese ebenfalls gleich, werden die Sekundenteile verglichen.

Bedingte logische Operatoren

Die Operatoren and und or werden als bedingte logische Operatoren bezeichnet.

logical-or-expression:
      logical-and-expression
logical-and-expression
orlogical-or-expression
logical-and-expression:
      is-expression
      is-expression
andlogical-and-expression

Der Operator or gibt true zurück, wenn mindestens einer der Operanden true ist. Der rechte Operand wird nur dann ausgewertet, wenn der linke Operand nicht true ist.

Der Operator and gibt false zurück, wenn mindestens einer der Operanden false ist. Der rechte Operand wird nur dann ausgewertet, wenn der linke Operand nicht false ist.

Die Wahrheitstabellen für die Operatoren or und and sind im Folgenden dargestellt, wobei das Ergebnis der Auswertung des linken Operandenausdrucks in der vertikalen Achse und das Ergebnis der Auswertung des rechten Operandenausdrucks in der horizontalen Achse angegeben ist.

and true false null error
true true false null error
false false false false false
null null false null error
error error error error error
or true false null error
or true false null error
true true true true true
false true false null error
null true null null error
error error error error error

Folgendes gilt beim Auswerten eines Ausdrucks, der bedingte logische Operatoren enthält:

  • Fehler, die beim Auswerten der Ausdrücke x und y ausgelöst werden, werden weitergegeben.

  • Die bedingten logischen Operatoren werden über die Typen logical und null definiert. Wenn die Operandenwerte diese Typen nicht aufweisen, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

  • Das Ergebnis ist ein logischer Wert.

  • Im Ausdruck x oder y wird der Ausdruck y nur dann ausgewertet, wenn x nicht mit true ausgewertet wird.

  • Im Ausdruck x und y wird der Ausdruck y nur dann ausgewertet, wenn x nicht mit false ausgewertet wird.

Den letzten beiden Eigenschaften verdanken die bedingten logischen Operatoren ihre Qualifikation „bedingt“. Eigenschaften werden auch als „Kurzschluss“ bezeichnet. Diese Eigenschaften sind nützlich, wenn Sie kompakte bewachte Prädikate schreiben möchten. Die folgenden Ausdrücke sind beispielsweise äquivalent:

d <> 0 and n/d > 1 if d <> 0 then n/d > 1 else false

Arithmetische Operatoren

Die Operatoren +, -, * und / sind die arithmetischen Operatoren.

additive-expression:
      multiplicative-expression
      additive-expression
+multiplicative-expression
      additive-expression
-multiplicative-expression
multiplicative-expression:
      metadata- expression
      multiplicative-expression
*metadata-expression
      multiplicative-expression
/metadata-expression

Genauigkeit

Zahlen in M werden mithilfe einer Vielzahl von Darstellungen gespeichert, um so viele Informationen wie möglich über Zahlen zu erhalten, die aus einer Vielzahl von Quellen stammen. Zahlen werden nur dann von einer Darstellung in eine andere konvertiert, wenn dies von den auf sie angewendeten Operatoren benötigt wird. In M werden zwei Genauigkeiten unterstützt:

Genauigkeit Semantik
Precision.Decimal 128-Bit-Dezimaldarstellung mit einem Bereich von ±1.0 x 10-28 bis ±7.9 x 1028 und 28-29 signifikanten Ziffern.
Precision.Double Wissenschaftliche Darstellung mit Mantisse und Exponent; entspricht den Regeln für 64-Bit-Binärzahlen mit doppelter Genauigkeit (Norm IEEE 754 für Arithmetik IEEE 754-2008).

Arithmetische Operationen werden durch Auswahl einer Genauigkeit durchgeführt. Dabei werden ggf. beide Operanden in diese Genauigkeit konvertiert. Anschließend wird die eigentliche Operation durchgeführt und eine Zahl in der ausgewählten Genauigkeit zurückgegeben.

Für die integrierten arithmetischen Operatoren (+, -, *, /) wird die doppelte Genauigkeit verwendet. Standardbibliotheksfunktionen (Value.Add, Value.Subtract, Value.Multiply, Value.Divide) können verwendet werden, um diese Operationen mit einem bestimmten Genauigkeitsmodell anzufordern.

  • Es ist kein numerischer Überlauf möglich: #infinity oder -#infinity stellt Werte von Größen dar, die für die Darstellung zu groß sind.

  • Es ist kein numerischer Unterlauf möglich: 0 und -0 stellt Werte von Größen dar, die für die Darstellung zu klein sind.

  • Der spezielle IEEE 754-Wert #nan (NaN – Not a Number, keine Zahl) wird verwendet, um arithmetisch ungültige Fälle abzudecken, z. B. die Division von Null durch Null.

  • Die Konvertierung von Dezimalzahlen in Zahlen mit doppelter Genauigkeit erfolgt durch das Runden von Dezimalzahlen auf den nächsten äquivalenten Wert mit doppelter Genauigkeit.

  • Die Konvertierung von Zahlen mit doppelter Genauigkeit in Dezimalzahlen erfolgt durch das Runden von Zahlen mit doppelter Genauigkeit auf den nächsten äquivalenten Dezimalwert und ggf. durch einen Überlauf auf #infinity- oder -#infinity-Werte.

Additionsoperator

Die Interpretation des Additionsoperators (x + y) ist wie folgt von der Art des Werts der ausgewerteten Ausdrücke x und y abhängig:

x Y Ergebnis Interpretation
type number type number type number Numerische Summe
type number null null
null type number null
type duration type duration type duration Numerische Summe von Größen
type duration null null
null type duration null
typedatetime type duration typedatetime Date-Offset nach duration
type duration typedatetime typedatetime
typedatetime null null
null typedatetime null

In der Tabelle steht typedatetime für type date, type datetime, type datetimezone oder type time. Beim Addieren eines duration-Werts mit einem Wert vom Typ datetime entspricht der resultierende Wert diesem Typ.

Bei anderen Kombinationen von Werten als den in der Tabelle aufgeführten Kombinationen wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst. Diese Kombinationen werden in den nachstehenden Abschnitten beschrieben.

Fehler, die beim Auswerten eines Operanden ausgelöst werden, werden weitergegeben.

Numerische Summe

Die Summe von zwei Zahlen wird mithilfe des Additionsoperators berechnet. Dabei wird eine Zahl erzeugt.

Beispiel:

1 + 1             // 2 
#nan + #infinity  // #nan

Der Additionsoperator + bei Zahlen verwendet doppelte Genauigkeit. Die Standardbibliotheksfunktion Value.Add kann zur Angabe der Dezimalgenauigkeit verwendet werden. Folgendes gilt beim Berechnen einer Summe von Zahlen:

  • Die Summe in doppelter Genauigkeit wird gemäß den Regeln für 64-Bit-Binärzahlen mit doppelter Genauigkeit (Norm IEEE 754 für Arithmetik IEEE 754-2008) berechnet. In der folgenden Tabelle sind die Ergebnisse für alle möglichen Kombinationen aus endlichen Werten ungleich Null, Nullen, unendlichen Werten und NaN-Werten aufgeführt. In der Tabelle sind x und y endliche Werte ungleich Null, und z ist das Ergebnis aus x + y. Wenn x und y die gleiche Größe jedoch andere Vorzeichen haben, ist z eine positive Null. Wenn x + y für die Darstellung im Zieltyp zu groß ist, ist z ein unendlicher Wert mit demselben Vorzeichen wie x + y.

    + Y +0 -0 +∞ -∞ NaN
    x z x x +∞ -∞ NaN
    +0 Y +0 +0 +∞ -∞ NaN
    -0 Y +0 -0 +∞ -∞ NaN
    +∞ +∞ +∞ +∞ +∞ NaN NaN
    -∞ -∞ -∞ -∞ NaN -∞ NaN
    NaN NaN NaN NaN NaN NaN NaN
  • Die Summe in Dezimalgenauigkeit wird unter Beibehaltung der Genauigkeit berechnet. Die Skala des Ergebnisses ist der größere der Skalen der beiden Operanden.

Summe der durations

Die Summe von zwei duration-Werten ist der duration-Wert, der die Summe aus der Anzahl der 100-Nanosekunden-Ticks darstellt, die durch die duration-Werte dargestellt werden. Beispiel:

#duration(2,1,0,15.1) + #duration(0,1,30,45.3) 
// #duration(2, 2, 31, 0.4)

Date-Offset nach duration

Ein datetime-Wert x und ein duration-Wert y können mit x + y addiert werden, um einen neuen datetime-Wert zu berechnen, dessen Abstand von x auf einer linearen Zeitskala exakt der Größe von y entspricht. Hier steht datetime für einen Date-, DateTime-, DateTimeZone- oder Time-Wert, und ein Ergebnis ungleich Null weist denselben Typ auf. Die datetime-Abweichung nach duration kann wie folgt berechnet werden:

  • Wenn der „days since epoch“-Wert des datetime-Werts angegeben wird, wird mit den folgenden Informationselementen ein neuer datetime-Wert erstellt:

    • Berechnen Sie einen neuen „days since epoch“-Wert, der der Division der Größe von y durch die Anzahl der 100-Nanosekunden-Ticks in einem Zeitraum von 24 Stunden entspricht, indem Sie den Dezimalteil des Ergebnisses abschneiden und diesen Wert mit dem „days since epoch“-Wert von x addieren.

    • Berechnen Sie einen neuen tick-Wert seit dem midnight-Wert, der der Addition der Größe von y mit den tick-Werten von x seit dem midnight-Wert entspricht, der dem Rest der Anzahl von 100-Nanosekunden-Ticks in einem Zeitraum von 24 Stunden entspricht. Wenn x keinen Wert für die Ticks seit Mitternacht angibt, wird ein Wert von 0 angenommen.

    • Kopieren Sie den Wert von x für die Minutenabweichung von der koordinierten Weltzeit unverändert.

  • Wenn der „days since epoch“-Wert des datetime-Werts nicht angegeben wird, wird ein neuer datetime-Wert erstellt, wobei die folgenden Informationselemente angegeben werden:

    • Berechnen Sie einen neuen tick-Wert seit dem midnight-Wert, der der Addition der Größe von y mit den tick-Werten von x seit dem midnight-Wert entspricht, der dem Rest der Anzahl von 100-Nanosekunden-Ticks in einem Zeitraum von 24 Stunden entspricht. Wenn x keinen Wert für die Ticks seit Mitternacht angibt, wird ein Wert von 0 angenommen.

    • Kopieren Sie die Werte von x für den „days since epoch“-Wert und die Minutenabweichung von der koordinierten Weltzeit unverändert.

In den folgenden Beispielen wird die Berechnung der absoluten temporalen Summe veranschaulicht, wenn der datetime-Wert den days since epoch-Wert angibt:

#date(2010,05,20) + #duration(0,8,0,0) 
    //#datetime( 2010, 5, 20, 8, 0, 0 ) 
    //2010-05-20T08:00:00 
 
#date(2010,01,31) + #duration(30,08,0,0) 
    //#datetime(2010, 3, 2, 8, 0, 0) 
    //2010-03-02T08:00:00 
 
#datetime(2010,05,20,12,00,00,-08) + #duration(0,04,30,00) 
    //#datetime(2010, 5, 20, 16, 30, 0, -8, 0) 
    //2010-05-20T16:30:00-08:00 
 
#datetime(2010,10,10,0,0,0,0) + #duration(1,0,0,0) 
   //#datetime(2010, 10, 11, 0, 0, 0, 0, 0) 
   //2010-10-11T00:00:00+00:00

Im folgenden Beispiel wird gezeigt, wie die datetime-Abweichung nach dem duration-Wert für einen bestimmten time-Wert berechnet wird:

#time(8,0,0) + #duration(30,5,0,0) 
   //#time(13, 0, 0) 
   //13:00:00

Subtraktionsoperator

Die Interpretation des Subtraktionsoperators (x - y) ist wie folgt von der Art des Werts der ausgewerteten Ausdrücke x und y abhängig:

x Y Ergebnis Interpretation
type number type number type number Numerische Differenz
type number null null
null type number null
type duration type duration type duration Numerische Differenz von Größen
type duration null null
null type duration null
typedatetime typedatetime type duration Duration zwischen datetimes
typedatetime type duration typedatetime Datetime-Offset nach negierter duration
typedatetime null null
null typedatetime null

In der Tabelle steht typedatetime für type date, type datetime, type datetimezone oder type time. Beim Subtrahieren eines duration-Werts von einem Wert vom Typ datetime entspricht der resultierende Wert diesem Typ.

Bei anderen Kombinationen von Werten als den in der Tabelle aufgeführten Kombinationen wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst. Diese Kombinationen werden in den nachstehenden Abschnitten beschrieben.

Fehler, die beim Auswerten eines Operanden ausgelöst werden, werden weitergegeben.

Numerische Differenz

Die Differenz zwischen zwei Zahlen wird mithilfe des Subtraktionsoperators berechnet. Dabei wird eine Zahl erzeugt. Beispiel:

1 - 1                // 0 
#nan - #infinity     // #nan

Der Subtraktionsoperator - bei Zahlen verwendet doppelte Genauigkeit. Die Standardbibliotheksfunktion Value.Subtract kann zur Angabe der Dezimalgenauigkeit verwendet werden. Folgendes gilt beim Berechnen einer Differenz zwischen Zahlen:

  • Die Differenz in doppelter Genauigkeit wird gemäß den Regeln für 64-Bit-Binärzahlen mit doppelter Genauigkeit (Norm IEEE 754 für Arithmetik IEEE 754-2008) berechnet. In der folgenden Tabelle sind die Ergebnisse für alle möglichen Kombinationen aus endlichen Werten ungleich Null, Nullen, unendlichen Werten und NaN-Werten aufgeführt. In der Tabelle sind x und y endliche Werte ungleich Null, und z ist das Ergebnis aus x - y. Wenn x und y gleich sind, ist z eine positive Null. Wenn x - y für die Darstellung im Zieltyp zu groß ist, ist z ein unendlicher Wert mit demselben Vorzeichen wie x - y.

    - Y +0 -0 +∞ -∞ NaN
    x z x x -∞ +∞ NaN
    +0 -y +0 +0 -∞ +∞ NaN
    -0 -y -0 +0 -∞ +∞ NaN
    +∞ +∞ +∞ +∞ NaN +∞ NaN
    -∞ -∞ -∞ -∞ -∞ NaN NaN
    NaN NaN NaN NaN NaN NaN NaN
  • Die Differenz in Dezimalgenauigkeit wird unter Beibehaltung der Genauigkeit berechnet. Die Skala des Ergebnisses ist der größere der Skalen der beiden Operanden.

Differenz der durations

Die Differenz zwischen zwei duration-Werten ist der duration-Wert, der die Differenz zwischen der Anzahl der 100-Nanosekunden-Ticks darstellt, die durch die einzelnen duration-Werte dargestellt werden. Beispiel:

#duration(1,2,30,0) - #duration(0,0,0,30.45) 
// #duration(1, 2, 29, 29.55)

Datetime-Offset nach negierter duration

Ein datetime-Wert x und ein duration-Wert y können zur Berechnung eines neuen datetime-Werts mit x - y subtrahiert werden. Hier steht datetime für date, datetime, datetimezone oder time. Der resultierende datetime-Wert weist auf einer linearen Zeitskala einen Abstand von x auf, der exakt der Größe von y entspricht und der in entgegengesetzter Richtung zum Vorzeichen von y verläuft. Die Subtraktion von positiven duration-Werten führt zu Ergebnissen, die relativ zu x zeitlich rückwärts gerichtet sind, während die Subtraktion von negativen Werten zu Ergebnissen führt, die zeitlich vorwärts gerichtet sind.

#date(2010,05,20) - #duration(00,08,00,00) 
   //#datetime(2010, 5, 19, 16, 0, 0) 
   //2010-05-19T16:00:00 
#date(2010,01,31) - #duration( 30,08,00,00) 
   //#datetime(2009, 12, 31, 16, 0, 0) 
   //2009-12-31T16:00:00

Duration-Werte zwischen datetime-Werten

Zwei datetime-Werte t und u können zur Berechnung des duration-Werts dazwischen mit t - u subtrahiert werden. Hier steht datetime für date, datetime, datetimezone oder time. Der duration-Wert, der sich aus der Subtraktion von u von t ergibt, muss bei der Addition mit ut ergeben.

#date(2010,01,31) - #date(2010,01,15) 
// #duration(16,00,00,00) 
// 16.00:00:00 
 
#date(2010,01,15)- #date(2010,01,31) 
// #duration(-16,00,00,00) 
// -16.00:00:00 
 
#datetime(2010,05,20,16,06,00,-08,00) - 
#datetime(2008,12,15,04,19,19,03,00) 
// #duration(521,22,46,41)
// 521.22:46:41

Die Subtraktion von t - u, wenn u > t, ergibt einen negativen duration-Wert:

#time(01,30,00) - #time(08,00,00) 
// #duration(0, -6, -30, 0)

Beim Subtrahieren zweier datetime-Werte mit t - u gilt Folgendes:

  • u + (t - u) = t

Multiplikationsoperator

Die Interpretation des Multiplikationsoperators (x * y) ist wie folgt von der Art des Werts der ausgewerteten Ausdrücke x und y abhängig:

X Y Ergebnis Interpretation
type number type number type number Numerisches Produkt
type number null null
null type number null
type duration type number type duration Vielfaches des duration-Werts
type number type duration type duration Vielfaches des duration-Werts
type duration null null
null type duration null

Bei anderen Kombinationen von Werten als den in der Tabelle aufgeführten Kombinationen wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst. Diese Kombinationen werden in den nachstehenden Abschnitten beschrieben.

Fehler, die beim Auswerten eines Operanden ausgelöst werden, werden weitergegeben.

Numerisches Produkt

Das Produkt von zwei Zahlen wird mithilfe des Multiplikationsoperators berechnet. Dabei wird eine Zahl erzeugt. Beispiel:

2 * 4                // 8 
6 * null             // null 
#nan * #infinity     // #nan

Der Multiplikationsoperator * bei Zahlen verwendet doppelte Genauigkeit. Die Standardbibliotheksfunktion Value.Multiply kann zur Angabe der Dezimalgenauigkeit verwendet werden. Folgendes gilt beim Berechnen eines Produkts aus Zahlen:

  • Das Produkt in doppelter Genauigkeit wird gemäß den Regeln für 64-Bit-Binärzahlen mit doppelter Genauigkeit (Norm IEEE 754 für Arithmetik IEEE 754-2008) berechnet. In der folgenden Tabelle sind die Ergebnisse für alle möglichen Kombinationen aus endlichen Werten ungleich Null, Nullen, unendlichen Werten und NaN-Werten aufgeführt. In der Tabelle sind x und y positive endliche Werte. z ist das Ergebnis von x * y. Wenn das Ergebnis für den Zieltyp zu groß ist, ist z ein unendlicher Wert. Wenn das Ergebnis für den Zieltyp zu klein ist, ist z Null.

    * +y -y +0 -0 +∞ -∞ NaN
    +x +z -Z +0 -0 +∞ -∞ NaN
    -x -Z +z -0 +0 -∞ +∞ NaN
    +0 +0 -0 +0 -0 NaN NaN NaN
    -0 -0 +0 -0 +0 NaN NaN NaN
    +∞ +∞ -∞ NaN NaN +∞ -∞ NaN
    -∞ -∞ +∞ NaN NaN -∞ +∞ NaN
    NaN NaN NaN NaN NaN NaN NaN NaN
  • Das Produkt in Dezimalgenauigkeit wird unter Beibehaltung der Genauigkeit berechnet. Die Skala des Ergebnisses ist der größere der Skalen der beiden Operanden.

Vielfache der duration-Werte

Das Produkt aus einem duration-Wert und einer Zahl ist der duration-Wert, der die Anzahl der 100-Nanosekunden-Ticks darstellt, die durch den duration-Operanden mal der Operandenanzahl dargestellt werden. Beispiel:

#duration(2,1,0,15.1) * 2 
// #duration(4, 2, 0, 30.2)

Divisionsoperator

Die Interpretation des Divisionsoperators (x / y) ist wie folgt von der Art des Werts der ausgewerteten Ausdrücke x und y abhängig:

X Y Ergebnis Interpretation
type number type number type number Numerischer Quotient
type number null null
null type number null
type duration type number type duration Bruch eines duration-Werts
type duration type duration type duration Numerischer Quotient von duration-Werten
type duration null null
null type duration null

Bei anderen Kombinationen von Werten als den in der Tabelle aufgeführten Kombinationen wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst. Diese Kombinationen werden in den nachstehenden Abschnitten beschrieben.

Fehler, die beim Auswerten eines Operanden ausgelöst werden, werden weitergegeben.

Numerischer Quotient

Der Quotient von zwei Zahlen wird mithilfe des Divisionsoperators berechnet. Dabei wird eine Zahl erzeugt. Beispiel:

8 / 2               // 4 
8 / 0               // #infinity 
0 / 0               // #nan 
0 / null            // null 
#nan / #infinity    // #nan

Der Divisionsoperator / bei Zahlen verwendet doppelte Genauigkeit. Die Standardbibliotheksfunktion Value.Divide kann zur Angabe der Dezimalgenauigkeit verwendet werden. Folgendes gilt beim Berechnen eines Quotienten aus Zahlen:

  • Der Quotient in doppelter Genauigkeit wird gemäß den Regeln für 64-Bit-Binärzahlen mit doppelter Genauigkeit (Norm IEEE 754 für Arithmetik IEEE 754-2008) berechnet. In der folgenden Tabelle sind die Ergebnisse für alle möglichen Kombinationen aus endlichen Werten ungleich Null, Nullen, unendlichen Werten und NaN-Werten aufgeführt. In der Tabelle sind x und y positive endliche Werte. z ist das Ergebnis von x / y. Wenn das Ergebnis für den Zieltyp zu groß ist, ist z ein unendlicher Wert. Wenn das Ergebnis für den Zieltyp zu klein ist, ist z Null.

    / +y -y +0 -0 +∞ -∞ NaN
    +x +z -Z +∞ -∞ +0 -0 NaN
    -x -Z +z -∞ +∞ -0 +0 NaN
    +0 +0 -0 NaN NaN +0 -0 NaN
    -0 -0 +0 NaN NaN -0 +0 NaN
    +∞ +∞ -∞ +∞ -∞ NaN NaN NaN
    -∞ -∞ +∞ -∞ +∞ NaN NaN NaN
    NaN NaN NaN NaN NaN NaN NaN NaN
  • Die Summe in Dezimalgenauigkeit wird unter Beibehaltung der Genauigkeit berechnet. Die Skala des Ergebnisses ist der größere der Skalen der beiden Operanden.

Quotient von duration-Werten

Der Quotient von zwei duration-Werten ist die Zahl, die den Quotienten aus der Anzahl der 100-Nanosekunden-Ticks darstellt, die durch die duration-Werte dargestellt werden. Beispiel:

#duration(2,0,0,0) / #duration(0,1,30,0) 
// 32

Skalierte duration-Werte

Der Quotient aus einem duration-Wert x und einer Zahl y ist der duration-Wert, der den Quotienten der Anzahl der 100-Nanosekunden-Ticks darstellt, die durch den duration-Wert x mal der Zahl y dargestellt werden. Beispiel:

#duration(2,0,0,0) / 32 
// #duration(0,1,30,0)

Strukturkombination

Der Kombinationsoperator (x & y) wird über die folgenden Arten von Werten definiert:

X Y Ergebnis Interpretation
type text type text type text Verkettung
type text null null
null type text null
type date type time type datetime Zusammenführen
type date null null
null type time null
type list type list type list Verkettung
type record type record type record Zusammenführen
type table type table type table Verkettung

Verkettung

Zwei Text-, zwei Listen- oder zwei Tabellenwerte können mit verkettet x & y werden.

Das folgende Beispiel veranschaulicht die Verkettung von Textwerten:

"AB" & "CDE"     // "ABCDE"

Das folgende Beispiel veranschaulicht die Verkettung von Listenwerten:

{1, 2} & {3}     // {1, 2, 3}

Folgendes gilt beim Verketten von zwei Werten mit x & y:

  • Fehler, die beim Auswerten der Ausdrücke x und y ausgelöst werden, werden weitergegeben.

  • Wenn ein Element von x oder y einen Fehler enthält, wird kein Fehler weitergegeben.

  • Das Ergebnis der Verkettung von zwei Textwerten ist ein Textwert, der den Wert von x direkt gefolgt von y enthält. Wenn einer der Operanden NULL und der andere ein Textwert ist, ist das Ergebnis NULL.

  • Das Ergebnis der Verkettung zweier Listen ist eine Liste, die alle Elemente von x gefolgt von allen Elementen von y enthält.

  • Das Ergebnis der Verkettung zweier Tabellen ist eine Tabelle, die die Kombination der Spalten der beiden Operandentabellen enthält. Die Spaltenreihenfolge von x wird beibehalten, gefolgt von den Spalten, die nur in y vorkommen, wobei deren relative Reihenfolge erhalten bleibt. Bei Spalten, die nur in einem Operanden vorkommen, wird null verwendet, um Zellwerte für den anderen Operanden auszufüllen.

Zusammenführen

Zusammenführung des Datensatzes

Zwei Datensätze können mit x & y zusammengeführt werden. Dabei wird ein Datensatz erzeugt, der Felder aus x und y enthält.

Die folgenden Beispiele veranschaulichen die Zusammenführung von Datensätzen:

[ x = 1 ] & [ y = 2 ]                // [ x = 1, y = 2 ] 
[ x = 1, y = 2 ] & [ x = 3, z = 4 ]  // [ x = 3, y = 2, z = 4 ]

Folgendes gilt beim Zusammenführen von zwei Datensätzen mit x + y:

  • Fehler, die beim Auswerten der Ausdrücke x und y ausgelöst werden, werden weitergegeben.

  • Wenn ein Feld sowohl in x als auch in y vorhanden ist, wird der Wert aus y verwendet.

  • Die Reihenfolge der Felder im resultierenden Datensatz entspricht der von x, gefolgt von Feldern in y, die nicht Teil von x sind, in derselben Reihenfolge, in der sie in y vorhanden sind.

  • Das Zusammenführen von Datensätzen führt nicht zur Auswertung der Werte.

  • Es wird kein Fehler ausgelöst, da ein Feld einen Fehler enthält.

  • Das Ergebnis ist ein Datensatz.

Zusammenführung von Datum und Uhrzeit

Ein date-Wert x kann mit einem time-Wert y mit x & y zusammengeführt werden und so einen datetime-Wert erzeugen, der die Teile aus x und y vereint.

Im folgenden Beispiel wird veranschaulicht, wie ein date- und ein time-Wert zusammengeführt werden:

#date(2013,02,26) & #time(09,17,00) 
// #datetime(2013,02,26,09,17,00)

Folgendes gilt beim Zusammenführen von zwei Datensätzen mit x + y:

  • Fehler, die beim Auswerten der Ausdrücke x und y ausgelöst werden, werden weitergegeben.

  • Das Ergebnis ist ein datetime-Wert.

Unäre Operatoren

Die Operatoren +, - und not sind unäre Operatoren.

unary-expression:
      type-expression

      +unärer Ausdruck
      -unärer Ausdruck
      notunärer Ausdruck

Unärer Plus-Operator

Der unäre Plus-Operator (+x) wird über die folgenden Arten von Werten definiert:

X Ergebnis Interpretation
type number type number Unäres Plus
type duration type duration Unäres Plus
null `null

Für andere Werte wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

Der unäre Plus-Operator lässt zu, dass ein +-Zeichen auf eine Zahl, einen datetime-Wert oder einen NULL-Wert angewendet wird. Das Ergebnis ist derselbe Wert. Beispiel:

+ - 1                 // -1 
+ + 1                 // 1 
+ #nan                // #nan 
+ #duration(0,1,30,0) // #duration(0,1,30,0)

Folgendes gilt beim Auswerten des unären Plus-Operators +x:

  • Fehler, die beim Auswerten von x ausgelöst werden, werden weitergegeben.

  • Wenn das Ergebnis der Auswertung von x kein Zahlenwert ist, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

Unärer Minus-Operator

Der unäre Minus-Operator (-x) wird über die folgenden Arten von Werten definiert:

X Ergebnis Interpretation
type number type number Negation
type duration type duration Negation
null null

Für andere Werte wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

Der unäre Minus-Operator wird verwendet, um das Vorzeichen eines Zahlen- oder duration-Werts zu ändern. Beispiel:

- (1 + 1)       // -2 
- - 1           // 1 
- - - 1         // -1 
- #nan          // #nan 
- #infinity     // -#infinity 
- #duration(1,0,0,0)  // #duration(-1,0,0,0) 
- #duration(0,1,30,0) // #duration(0,-1,-30,0)

Folgendes gilt beim Auswerten des unären Minus-Operators -x:

  • Fehler, die beim Auswerten von x ausgelöst werden, werden weitergegeben.

  • Wenn der Ausdruck eine Zahl ist, ist das Ergebnis der Zahlenwert aus dem Ausdruck x, dessen Vorzeichen geändert wurde. Wenn der Wert ein NaN-Wert ist, ist das Ergebnis ebenfalls ein NaN-Wert.

Logischer Negationsoperator:

Der logische Negationsoperator (not) wird über die folgenden Arten von Werten definiert:

X Ergebnis Interpretation
type logical type logical Negation
null null

Dieser Operator berechnet die logische not-Operation für einen gegebenen logischen Wert. Beispiel:

not true             // false 
not false            // true 
not (true and true)  // false

Folgendes gilt beim Auswerten des logischen Negationsoperators not x:

  • Fehler, die beim Auswerten von x ausgelöst werden, werden weitergegeben.

  • Der durch die Auswertung von Ausdruck x erzeugte Wert muss ein logischer Wert sein, da andernfalls ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst wird. Wenn der Wert true ist, ist das Ergebnis false. Wenn der Operand false ist, ist das Ergebnis true.

Das Ergebnis ist ein logischer Wert.

Typoperatoren

Die Operatoren is und as werden als Typoperatoren bezeichnet.

Typkompatibilitätsoperator

Der Typkompatibilitätsoperator x is y wird über die folgenden Werttypen definiert:

X Y Ergebnis
type any nullable-primitive-type type logical

Der Ausdruck x is y gibt true zurück, wenn der zugeschriebene Typ von x mit y kompatibel ist. Er gibt false zurück, wenn der zugeschriebene Typ von x mit y nicht kompatibel ist. y muss ein nullable-primitivetype-Typ sein.

is-expression:
      as-expression
      is-expression
isnullable-primitive-type
nullable-primitive-type:

      nullableopt primitive-type

Die Typkompatibilität, wie sie vom is-Operator unterstützt wird, ist eine Teilmenge der allgemeinen Typkompatibilität und wird anhand der folgenden Regeln definiert:

  • Wenn x NULL ist, ist der Ausdruck kompatibel, sofern y der Typ any, der Typ null oder ein Typ ist, der NULL-Werte zulässt.

  • Wenn x ungleich NULL ist, ist der Ausdruck kompatible, sofern der primitive Typ von x mit y identisch ist.

Folgendes gilt beim Auswerten des Ausdrucks x is y:

  • Ein Fehler, der beim Auswerten des Ausdrucks x ausgelöst wird, wird weitergegeben.

Typassertionsoperator

Der Typassertionsoperator x as y wird über die folgenden Werttypen definiert:

X Y Ergebnis
type any nullable-primitive-type type any

Der Ausdruck x as y bestätigt, dass der Wert x mit y gemäß dem is-Operator kompatibel ist. Ist er nicht kompatibel, wird ein Fehler ausgelöst. y muss ein nullable-primitive-type-Typ sein.

as-expression:
      equality-expression
      as-expression
asnullable-primitive-type

Der Ausdruck x as y wird wie folgt ausgewertet:

  • Eine Typkompatibilitätsprüfung x is y wird durchgeführt, und die Assertion gibt x unverändert zurück, wenn diese Prüfung erfolgreich verläuft.

  • Wenn die Kompatibilitätsprüfung fehlschlägt, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

Beispiele:

1 as number               // 1 
"A" as number             // error 
null as nullable number   // null

Folgendes gilt beim Auswerten des Ausdrucks x as y:

  • Ein Fehler, der beim Auswerten des Ausdrucks x ausgelöst wird, wird weitergegeben.

Coalesce-Operator

Der Coalesce-Operator ?? gibt das Ergebnis seines linken Operanden zurück, wenn er nicht NULL ist. Andernfalls gibt er das Ergebnis seines rechten Operanden zurück. Der rechte Operand wird nur dann ausgewertet, wenn der linke Operand nicht NULL ist.