Dela via


Operatörsbeteende

Det här avsnittet definierar beteendet för de olika M-operatorerna.

Prioritet för operator

När ett uttryck innehåller flera operatorer styr operatorernas prioritet i vilken ordning de enskilda operatorerna utvärderas. Uttrycket x + y * z utvärderas till exempel som x + (y * z) eftersom operatorn * har högre prioritet än den binära + operatorn. Prioriteten för en operator fastställs genom definitionen av dess associerade grammatikproduktion. Till exempel består ett additivt uttryck av en sekvens av multiplicativa uttryck avgränsade med + eller - operatorer, vilket ger + operatorerna och - lägre prioritet än operatorerna * och / .

Parentes-uttrycksproduktionen kan användas för att ändra standardprioretsordningen.

parentes-expression:
      ( uttryck )

Till exempel:

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

I följande tabell sammanfattas M-operatorerna och operatorkategorierna visas i prioritetsordning från högsta till lägsta. Operatorer i samma kategori har samma prioritet.

Kategori Uttryck beskrivning
Primär jag
@jag
Identifieraruttryck
(x) Parenteserat uttryck
x[i] Sökning
x{y} Objektåtkomst
x(...) Funktionsanrop
{x, y, ...} Listinitiering
[ i = x, ... ] Postinitiering
... Inte implementerad
Unär +x Identitet
-x Negation
notx Logisk negation
Metadata x meta y Associera metadata
Multiplicative x * y Multiplikation
x / y Division
Tillsats x + y Tillägg
x - y Subtraktion
Relation x < y Mindre än
x > y Större än
x <= y Mindre än eller lika med
x >= y Större än eller lika med
Tillämplig x = y Lika med
x <> y Not equal
Typkontroll x as y Är kompatibel null-primitiv typ eller fel
Typefterlevnad x is y Testa om kompatibel null-primitiv typ
Logiskt OCH x and y Kortslutningskonjunktion
Logiskt ELLER x or y Kortslutningsdisjunction
Coalesce x ?? y Null-sammankopplingsoperator

Operatorer och metadata

Varje värde har ett associerat postvärde som kan innehålla ytterligare information om värdet. Den här posten kallas metadataposten för ett värde. En metadatapost kan associeras med alla typer av värden, till och med null. Resultatet av en sådan association är ett nytt värde med angivna metadata.

En metadatapost är bara en vanlig post och kan innehålla alla fält och värden som en vanlig post kan, och i sig har en metadatapost. Att associera en metadatapost med ett värde är "icke-påträngande". Det ändrar inte värdets beteende i utvärderingar förutom de som uttryckligen inspekterar metadataposter.

Varje värde har en standardmetadatapost, även om en inte har angetts. Standardmetadataposten är tom. I följande exempel visas åtkomst till metadataposten för ett textvärde med hjälp av standardbiblioteksfunktionen Value.Metadata :

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

Metadataposter bevaras vanligtvis inte när ett värde används med en operator eller funktion som konstruerar ett nytt värde. Om till exempel två textvärden sammanfogas med operatorn & är metadata för det resulterande textvärdet den tomma posten []. Följande uttryck är likvärdiga:

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

Standardbiblioteksfunktionerna Value.RemoveMetadata och Value.ReplaceMetadata kan användas för att ta bort alla metadata från ett värde och för att ersätta ett värdes metadata (i stället för att sammanfoga metadata till befintliga metadata).

Den enda operator som returnerar resultat som bär metadata är metaoperatorn.

Strukturellt rekursiva operatorer

Värden kan vara cykliska. Till exempel:

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

M hanterar cykliska värden genom att hålla konstruktionen av poster, listor och tabeller lat. Ett försök att konstruera ett cykliskt värde som inte drar nytta av interjected lazy structured values ger ett fel:

[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"), 
// ]

Vissa operatorer i M definieras av strukturell rekursion. Till exempel definieras likhet mellan poster och listor av den sammanlänkade likheten mellan motsvarande postfält respektive objektlistor.

För icke-cykliska värden ger tillämpning av strukturell rekursion en begränsad utökning av värdet: delade kapslade värden kommer att korsas upprepade gånger, men rekursionsprocessen avslutas alltid.

Ett cykliskt värde har en oändlig expansion vid tillämpning av strukturell rekursion. Semantiken i M gör inga särskilda boenden för sådana oändliga expansioner – ett försök att jämföra cykliska värden för likhet, till exempel, kommer vanligtvis att få slut på resurser och avslutas exceptionellt.

Markerings- och projektionsoperatorer

Markerings- och projektionsoperatorerna tillåter att data extraheras från list- och postvärden.

Objektåtkomst

Ett värde kan väljas från en lista eller tabell baserat på dess nollbaserade position i listan eller tabellen med hjälp av ett objektåtkomstuttryck.

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

Item-access-expression x{y} returnerar:

  • För en lista x och ett tal y, objektet i listan x på position y. Det första objektet i en lista anses ha ett ordningstalsindex på noll. Om den begärda positionen inte finns i listan utlöses ett fel.

  • För en tabell x och ett tal y, raden i tabellen x på position y. Den första raden i en tabell anses ha ett ordningstalsindex på noll. Om den begärda positionen inte finns i tabellen utlöses ett fel.

  • För en tabell x och en post ymatchar den tabellrad x som matchar fältvärdena för post y för fält med fältnamn som matchar motsvarande tabellkolumnnamn. Om det inte finns någon unik matchande rad i tabellen utlöses ett fel.

Till exempel:

{"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

Item-access-expression stöder också formuläret x{y}?, som returnerar null när position (eller matchning) y inte finns i listan eller tabellen x. Om det finns flera matchningar för ygenereras fortfarande ett fel.

Till exempel:

{"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

Objektåtkomst tvingar inte utvärdering av andra list- eller tabellobjekt än den som används. Till exempel:

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

Följande gäller när objektets åtkomstoperator x{y} utvärderas:

  • Fel som uppstår under utvärderingen av uttryck x eller y sprids.

  • Uttrycket x skapar en lista eller ett tabellvärde.

  • Uttrycket y genererar ett talvärde eller, om x det genererar ett tabellvärde, ett postvärde.

  • Om y genererar ett talvärde och värdet för y är negativt genereras ett fel med orsakskoden "Expression.Error" .

  • Om y genererar ett talvärde och värdet y för är större än eller lika med antalet xutlöses ett fel med orsakskoden "Expression.Error" om inte det valfria operatorformuläret x{y}? används, i vilket fall värdet null returneras.

  • Om x skapar ett tabellvärde och y genererar ett postvärde och det inte finns några matchningar för y i xgenereras ett fel med orsakskoden "Expression.Error" om inte det valfria operatorformuläret x{y}? används, i vilket fall värdet null returneras.

  • Om x skapar ett tabellvärde och y genererar ett postvärde och det finns flera matchningar för y i xgenereras ett fel med orsakskoden "Expression.Error" .

Inga andra objekt x i än den positionen y utvärderas under processen för objektval. (För direktuppspelningslistor eller tabeller hoppas objekten eller raderna före position y över, vilket kan orsaka deras utvärdering, beroende på källan till listan eller tabellen.)

Fältåtkomst

Field-access-expression används för att välja ett värde från en post eller för att projicera en post eller tabell till ett med färre fält eller kolumner.

field-access-expression:
      fältval
      implicit-target-field-selection
      projektion
      implicit målprojektion
fältval:
      fältväljare för primärt uttryck
field-selector:
      required-field-selector
      optional-field-selector
required-field-selector:

      [ fältnamn ]
optional-field-selector:
      [ fältnamn ] ?
field-name:
      generalized-identifier
      quoted-identifier
implicit-target-field-selection:
      fältväljare
projektion:
      primary-expression required-projection
      primary-expression optional-projection
obligatorisk projektion:

      [required-selector-list ]
optional-projection:
      [required-selector-list ] ?
required-selector-list:
      required-field-selector
      required-selector-list
, required-field-selector
implicit målprojektion:
      obligatorisk projektion
      optional-projection

Den enklaste formen av fältåtkomst är obligatorisk fältval. Den använder operatorn x[y] för att leta upp ett fält i en post efter fältnamn. Om fältet y inte finns i xgenereras ett fel. Formuläret x[y]? används för att utföra val av valfritt fält och returnerar null om det begärda fältet inte finns i posten.

Till exempel:

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

Kollektiv åtkomst för flera fält stöds av operatorerna för nödvändig postprojektion och valfri postprojektion. Operatorn x[[y1],[y2],...] projicerar posten till en ny post med färre fält (valda av y1, y2, ...). Om ett markerat fält inte finns utlöses ett fel. Operatorn x[[y1],[y2],...] projicerar posten till en ny post med fälten valda av y1, y2, ..., , om ett fält saknas, null används i stället. Till exempel:

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

Formulären [y] och [y]? stöds som en kortfattad referens till identifieraren _ (understreck). Följande två uttryck är likvärdiga:

[A]                 
_[A]

I följande exempel visas den korta formen av fältåtkomst:

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

Formuläret [[y1],[y2],...] och [[y1],[y2],...]? stöds också som en förkortning och följande två uttryck är på samma sätt likvärdiga:

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

Det kortfattade formuläret är särskilt användbart i kombination med förkortningen each , ett sätt att introducera en funktion av en enskild parameter med namnet _ (mer information finns i Förenklade deklarationer. Tillsammans förenklar de två förkortningarna vanliga funktionella uttryck i högre ordning:

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

Ovanstående uttryck motsvarar följande mer kryptiska långhandsuttryck:

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

Fältåtkomst tvingar inte utvärdering av andra fält än de som används. Till exempel:

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

Följande gäller när en fältåtkomstoperator x[y], x[y]?, x[[y]]eller x[[y]]? utvärderas:

  • Fel som uppstår under utvärderingen av uttrycket x sprids.

  • Fel som uppstår vid utvärdering av fält y associeras permanent med fältet yoch sprids sedan. All framtida åtkomst till fältet y genererar det identiska felet.

  • Uttrycket x genererar ett post- eller tabellvärde, eller så utlöses ett fel.

  • Om identifieraren namnger y ett fält som inte finns i xgenereras ett fel med orsakskoden "Expression.Error" om inte det valfria operatorformuläret ...? används, i vilket fall värdet null returneras.

Inga andra fält x än de som namnges av y utvärderas under fältåtkomstprocessen.

Metadataoperator

Metadataposten för ett värde ändras med metaoperatorn (x meta y).

metadata-expression:
      unary-expression
      unary-expression
meta unary-expression

I följande exempel skapas ett textvärde med en metadatapost med operatorn meta och åtkomst till metadataposten för det resulterande värdet med hjälp av Value.Metadata:

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

Följande gäller vid användning av metadata som kombinerar operatorn x meta y:

  • Fel som uppstår när du utvärderar x eller y uttryck sprids.

  • Uttrycket y måste vara en post, eller så utlöses ett fel med orsakskoden "Expression.Error" .

  • Den resulterande metadataposten är xmetadataposten som sammanfogats med y. (För semantiken för sammanslagning av poster, se Koppla poster.)

  • Det resulterande värdet är värdet från x uttrycket, utan dess metadata, med den nyligen beräknade metadataposten kopplad.

Standardbiblioteksfunktionerna Value.RemoveMetadata och Value.ReplaceMetadata kan användas för att ta bort alla metadata från ett värde och för att ersätta ett värdes metadata (i stället för att sammanfoga metadata till befintliga metadata). Följande uttryck är likvärdiga:

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

Likhetsoperatorer

Likhetsoperatorn = används för att avgöra om två värden är lika. Ojämlikhetsoperatorn <> används för att avgöra om två värden inte är lika med.

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

Till exempel:

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

Metadata är inte en del av likhets- eller ojämlikhetsjämförelse. Till exempel:

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

Följande gäller när likhetsoperatorerna x = y tillämpas och x <> y:

  • Fel som uppstår när du utvärderar x eller y uttryck sprids.

  • Operatorn = har ett resultat av true om värdena är lika och false i annat fall.

  • Operatorn <> har ett resultat av false om värdena är lika och true i annat fall.

  • Metadataposter ingår inte i jämförelsen.

  • Om värden som skapas genom utvärdering av uttrycken x och y inte är samma typ av värde är värdena inte lika.

  • Om värdena som skapas genom utvärdering x av uttrycket och y är samma typ av värde finns det specifika regler för att avgöra om de är lika, enligt definitionen nedan.

  • Följande är alltid sant:

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

Likhetsoperatorerna definieras för följande typer:

  • Värdet null är bara lika med sig självt.
    null = null    // true 
    null = true    // false 
    null = false   // false
  • De logiska värdena true och false är bara lika med sig själva. Till exempel:
    true = true      // true 
    false = false    // true 
    true = false     // false 
    true = 1         // false
  • Tal jämförs med den angivna precisionen:

    • Om något av talen är #nanär talen inte samma.

    • När inget av talen är #nanjämförs talen med hjälp av en bitvis jämförelse av det numeriska värdet.

    • #nan är det enda värde som inte är lika med sig självt.

      Till exempel:

        1 = 1,              // true 
        1.0 = 1             // true 
        2 = 1               // false 
        #nan = #nan         // false 
        #nan <> #nan        // true
  • Två varaktigheter är lika med om de representerar samma antal tick på 100 nanosekunder.

  • Två gånger är lika med om storleken på deras delar (timme, minut, sekund) är lika.

  • Två datum är lika med om storleken på deras delar (år, månad, dag) är lika med.

  • Två datetimes är lika med om storleken på deras delar (år, månad, dag, timme, minut och sekund) är lika.

  • Två datetimezones är lika med om motsvarande UTC-datetimes är lika. För att komma fram till motsvarande UTC-datetime subtraheras förskjutningen timmar/minuter från datetime-komponenten i datetimezone.

  • Två textvärden är lika med om de använder en ordningstalskänslig, skiftlägeskänslig, kulturokänslig jämförelse med samma längd och lika med tecken på motsvarande positioner.

  • Två listvärden är lika med om alla följande är sanna:

    • Båda listorna innehåller samma antal objekt.

    • Värdena för varje positionsmässigt motsvarande objekt i listorna är lika med. Det innebär att listorna inte bara behöver innehålla samma objekt, utan att objekten måste vara i samma ordning.

      Till exempel:

        {1, 2} = {1, 2}     // true 
        {2, 1} = {1, 2}     // false 
        {1, 2, 3} = {1, 2}  // false
      
  • Två poster är lika med om alla följande är sanna:

    • Antalet fält är detsamma.

    • Varje fältnamn för en post finns också i den andra posten.

    • Värdet för varje fält i en post är lika med fältet med samma namn i den andra posten.

      Till exempel:

        [ 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
      
  • Två tabeller är lika om alla följande är sanna:

    • Antalet kolumner är detsamma.

    • Varje kolumnnamn i en tabell finns också i den andra tabellen.

    • Antalet rader är detsamma.

    • Varje rad har samma värden i motsvarande celler.

      Till exempel:

        #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
      
  • Ett funktionsvärde är lika med sig självt, men kan vara lika med ett annat funktionsvärde. Om två funktionsvärden anses vara lika beter de sig identiskt när de anropas.

    Två angivna funktionsvärden har alltid samma likhetsrelation.

  • Ett typvärde är lika med sig självt, men kan vara lika med ett annat typvärde. Om två typvärden anses vara lika beter de sig identiskt när de efterfrågas för överensstämmelse.

    Två angivna typvärden har alltid samma likhetsrelation.

Relationsoperatorer

Operatorerna <, >, <=och >= kallas för relationsoperatorer.

relational-expression:
      additivt uttryck
      relationellt uttryck för additivt uttryck
<
      relationellt uttryck för additivt uttryck
>
      additivt uttryck
<= _relational-uttryck
      relationellt uttryck för additivt uttryck >=

Dessa operatorer används för att fastställa den relativa ordningsrelationen mellan två värden, enligt följande tabell:

Åtgärd Result
x < y true om x är mindre än y, false annars
x > y true om x är större än y, false annars
x <= y true om x är mindre än eller lika med y, false annars
x >= y true om x är större än eller lika med y, false annars

Till exempel:

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

Följande gäller vid utvärdering av ett uttryck som innehåller relationsoperatorerna:

  • Fel som uppstår vid utvärdering av operanduttrycken x sprids y .

  • Värdena som skapas genom utvärdering av både uttrycken x och y måste vara ett binärt värde, datum, datetime, datetimezone, varaktighet, logiskt värde, tal, null, text eller tid. Annars utlöses ett fel med orsakskoden "Expression.Error" .

  • Båda operanderna måste ha samma typ av värde eller null. Annars utlöses ett fel med orsakskoden "Expression.Error" .

  • Om antingen eller båda operanderna är nullär null resultatet värdet.

  • Två binärfiler jämförs byte per byte.

  • Två datum jämförs genom att jämföra deras årsdelar och, om de är lika, deras månadsdelar och, om de är lika, deras dagdelar.

  • Två datetimes jämförs genom att jämföra deras årsdelar och, om de är lika, deras månadsdelar och, om de är lika, deras dagdelar och, om de är lika, deras timdelar och, om de är lika, deras minutdelar och, om de är lika, deras andra delar.

  • Två datetimezones jämförs genom att normalisera dem till UTC genom att subtrahera deras tim-/minutförskjutning och sedan jämföra deras datetime-komponenter.

  • Två varaktigheter jämförs enligt det totala antalet tick på 100 nanosekunder som de representerar.

  • Två logiska värden jämförs så att de true anses vara större än false.

  • Två tal x och y jämförs enligt reglerna i IEEE 754-standarden:

    • Om någon av operanderna är #nanär false resultatet för alla relationsoperatorer.

    • När ingen av operanderna är #nanjämför operatorerna värdena för de två flyttalsopernderna med avseende på ordningen -∞ < -max < ... < -min < -0.0 = +0.0 < +min < ... < +max < +∞ där min och max är de minsta och största positiva finita värdena som kan representeras. M-namnen för -∞ och +∞ är -#infinity och #infinity.

      Viktiga effekter av den här ordningen är:

      • Negativa och positiva nollor anses vara lika.

      • Ett -#infinity värde anses vara mindre än alla andra talvärden, men lika med ett annat -#infinity.

      • Ett #infinity värde anses vara större än alla andra talvärden, men lika med ett annat #infinity.

  • Två texter jämförs med hjälp av en ordningstalstal, skiftlägeskänslig, kulturokänslig jämförelse.

  • Två gånger jämförs genom att jämföra deras timdelar och, om de är lika, deras minutdelar och, om de är lika, deras andra delar.

Villkorsstyrda logiska operatorer

Operatorerna and och or kallas för villkorsstyrda logiska operatorer.

logical-or-expression:
      logical-and-expression
logical-and-expression
or logical-or-expression
logical-and-expression:
      is-expression
      is-expression
and logical-and-expression

Operatorn or returnerar true när minst en av dess operander är true. Den högra operanden utvärderas om och endast om den vänstra operanden inte trueär .

Operatorn and returnerar false när minst en av dess operander är false. Den högra operanden utvärderas om och endast om den vänstra operanden inte falseär .

Sanningstabeller för operatorerna or och and visas nedan, med resultatet av utvärderingen av det vänstra operanduttrycket på den lodräta axeln och resultatet av utvärderingen av det högra operanduttrycket på den vågräta axeln.

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

Följande gäller när du utvärderar ett uttryck som innehåller villkorsstyrda logiska operatorer:

  • Fel som uppstår när du utvärderar x eller y uttryck sprids.

  • De villkorsstyrda logiska operatorerna definieras över typerna logical och null. Om operandvärdena inte är av dessa typer utlöses ett fel med orsakskoden "Expression.Error" .

  • Resultatet är ett logiskt värde.

  • I uttrycket x eller yutvärderas uttrycket y om och endast om x inte utvärderas till true.

  • I uttrycket x och yutvärderas uttrycket y om och endast om x inte utvärderas till false.

De två sista egenskaperna ger de villkorsstyrda logiska operatorerna sin "villkorsstyrda" kvalificering. egenskaper som även kallas "kortslutning". De här egenskaperna är användbara för att skriva kompakta skyddade predikat. Följande uttryck är till exempel likvärdiga:

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

Aritmetiska operatorer

Operatorerna +, -och / * är de aritmetiska operatorerna.

additivt uttryck:
      multiplicativt uttryck
      additivt uttryck
+ multiplicativt uttryck
      additivt uttryck
- multiplicativt uttryck
multiplicative-expression:
      metadata- uttryck
      metadatauttryck för multiplicative-expression
*
      metadatauttryck för multiplicative-expression
/

Precision

Tal i M lagras med hjälp av en mängd olika representationer för att behålla så mycket information som möjligt om tal som kommer från en mängd olika källor. Tal konverteras endast från en representation till en annan efter behov av operatorer som tillämpas på dem. Två precisioner stöds i M:

Precision Semantik
Precision.Decimal 128-bitars decimalrepresentation med ett intervall på ±1,0 x 10–28 till ±7,9 x 1028 och 28–29 signifikanta siffror.
Precision.Double Vetenskaplig representation med mantissa och exponent; överensstämmer med den 64-bitars binära dubbelprecisionen IEEE 754 aritmetiska standard-IEEE 754-2008.

Aritmetiska åtgärder utförs genom att välja en precision, konvertera båda operanderna till den precisionen (om det behövs), sedan utföra den faktiska åtgärden och slutligen returnera ett tal i den valda precisionen.

De inbyggda aritmetiska operatorerna (+, -, *, /) använder dubbel precision. Standardbiblioteksfunktioner (Value.Add, Value.Subtract, Value.Multiply, Value.Divide) kan användas för att begära dessa åtgärder med hjälp av en specifik precisionsmodell.

  • Inget numeriskt spill är möjligt: #infinity eller -#infinity representera värden med för stora magnituder för att representeras.

  • Inget numeriskt underflöde är möjligt: 0 och -0 representerar värden med magnituder som är för små för att representeras.

  • Specialvärdet #nan IEEE 754 (NaN – Inte ett tal) används för att täcka aritmetiskt ogiltiga fall, till exempel en division med noll med noll.

  • Konvertering från decimal till dubbel precision utförs genom avrundning av decimaltal till närmaste motsvarande dubbla värde.

  • Konvertering från Dubbel till Decimal precision utförs genom avrundning av dubbla tal till närmaste ekvivalent decimalvärde och vid behov spills över till #infinity eller -#infinity värden.

additionsoperator

Tolkningen av additionsoperatorn (x + y) är beroende av typen av värde för de utvärderade uttrycken x och y enligt följande:

x y Result Tolkning
type number type number type number Numerisk summa
type number null null
null type number null
type duration type duration type duration Numerisk summa av magnituder
type duration null null
null type duration null
typedatetime type duration typedatetime Datetime-förskjutning efter varaktighet
type duration typedatetime typedatetime
typedatetime null null
null typedatetime null

I tabellen type står datetime för någon av type date, type datetime, type datetimezoneeller type time. När du lägger till en varaktighet och ett värde av någon typ datetime är det resulterande värdet av samma typ.

För andra kombinationer av värden än de som anges i tabellen genereras ett fel med orsakskoden "Expression.Error" . Varje kombination beskrivs i följande avsnitt.

Fel som uppstår vid utvärdering av någon av operanderna sprids.

Numerisk summa

Summan av två tal beräknas med hjälp av additionsoperatorn, vilket ger ett tal.

Till exempel:

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

Additionsoperatorn + över tal använder dubbel precision. Standardbiblioteksfunktionen Value.Add kan användas för att ange decimalprecision. Följande gäller vid beräkning av en summa tal:

  • Summan i Dubbel precision beräknas enligt reglerna för 64-bitars binär dubbelprecision IEEE 754 aritmetik IEEE 754-2008. I följande tabell visas resultatet av alla möjliga kombinationer av icke-ändliga värden, nollor, infiniteter och NaN:er. I tabellen x , och y är ickezero ändliga värden, och z är resultatet av x + y. Om x och y har samma storlek men motsatta tecken, z är positiv noll. Om x + y är för stort för att representeras i måltypen är z en oändlighet med samma tecken som 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
  • Summan i decimalprecision beräknas utan att precisionen går förlorad. Resultatets skala är den större av de två operandernas skalor.

Summa av varaktigheter

Summan av två varaktigheter är varaktigheten som representerar summan av antalet tick på 100nanosecond som representeras av varaktigheterna. Till exempel:

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

Datetime-förskjutning efter varaktighet

En datetime x och en varaktighet y kan läggas till med hjälp av x + y för att beräkna en ny datetime vars avstånd från x på en linjär tidslinje är exakt storleken på y. Här står datetime för något av Date, DateTime, DateTimeZoneeller Time och ett resultat som inte är null kommer att vara av samma typ. Datetime-förskjutningen efter varaktighet kan beräknas på följande sätt:

  • Om datetimes dagar sedan epokvärdet har angetts skapar du en ny datetime med följande informationselement:

    • Beräkna en ny dag sedan epok som motsvarar att dividera storleken på y med antalet tick på 100 nanosekunder under en 24-timmarsperiod, trunkera decimaldelen av resultatet och lägga till det här värdet till x-dagarna sedan epoken.

    • Beräkna nya fästingar sedan midnatt, vilket motsvarar att lägga till storleken y till x:ets fästingar sedan midnatt, och ange antalet tick på 100 nanosekunder under en 24-timmarsperiod. Om x inte anger något värde för fästingar sedan midnatt antas värdet 0.

    • Kopiera x-värdet för minuter förskjutning från UTC oförändrat.

  • Om datetimes dagar sedan epokvärdet är ospecificerat skapar du en ny datetime med följande informationselement angivna:

    • Beräkna nya fästingar sedan midnatt, vilket motsvarar att lägga till storleken y till x:ets fästingar sedan midnatt, och ange antalet tick på 100 nanosekunder under en 24-timmarsperiod. Om x inte anger något värde för fästingar sedan midnatt antas värdet 0.

    • Kopiera x-värden för dagar sedan epok och minuter förskjutning från UTC oförändrat.

I följande exempel visas beräkning av den absoluta temporala summan när datetime anger dagarna sedan epoken:

#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

I följande exempel visas beräkning av datetime-förskjutningen efter varaktighet för en viss tid:

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

subtraktionsoperator

Tolkningen av subtraktionsoperatorn (x - y) är beroende av typen av värdet för de utvärderade uttrycken x och y, enligt följande:

x Y Result Tolkning
type number type number type number Numerisk skillnad
type number null null
null type number null
type duration type duration type duration Numerisk skillnad mellan magnituder
type duration null null
null type duration null
typedatetime typedatetime type duration Varaktighet mellan datetimes
typedatetime type duration typedatetime Datetime-förskjutning efter negerad varaktighet
typedatetime null null
null typedatetime null

I tabellen type står datetime för någon av type date, type datetime, type datetimezoneeller type time. När du subtraherar en varaktighet från ett värde av någon typ datetime, är det resulterande värdet av samma typ.

För andra kombinationer av värden än de som anges i tabellen genereras ett fel med orsakskoden "Expression.Error" . Varje kombination beskrivs i följande avsnitt.

Fel som uppstår vid utvärdering av någon av operanderna sprids.

Numerisk skillnad

Skillnaden mellan två tal beräknas med hjälp av subtraktionsoperatorn, vilket ger ett tal. Till exempel:

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

Subtraktionsoperatorn - över tal använder dubbel precision. Standardbiblioteksfunktionen Value.Subtract kan användas för att ange decimalprecision. Följande gäller vid beräkning av en skillnad mellan tal:

  • Skillnaden i dubbel precision beräknas enligt reglerna för 64-bitars binär dubbelprecision IEEE 754 aritmetik IEEE 754-2008. I följande tabell visas resultatet av alla möjliga kombinationer av icke-ändliga värden, nollor, infiniteter och NaN:er. I tabellen x , och y är ickezero ändliga värden, och z är resultatet av x - y. Om x och y är lika med, z är positiv noll. Om x - y är för stort för att representeras i måltypen är z en oändlighet med samma tecken som 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
  • Skillnaden i decimalprecision beräknas utan att precisionen går förlorad. Resultatets skala är den större av de två operandernas skalor.

Skillnad mellan varaktigheter

Skillnaden mellan två varaktigheter är varaktigheten som representerar skillnaden mellan antalet tick på 100 nanosekunder som representeras av varje varaktighet. Till exempel:

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

Datetime-förskjutning efter negerad varaktighet

En datetime x och en varaktighet y kan subtraheras med hjälp av x - y för att beräkna en ny datetime. Här står datetime för någon av date, datetime, datetimezoneeller time. Den resulterande datetime har ett avstånd från x på en linjär tidslinje som är exakt storleken ypå , i riktning mot tecknet för y. Om du subtraherar positiva varaktigheter returneras resultat som är bakåt i tiden i förhållande till x, medan subtrahering av negativa värden ger resultat som är framåt i tiden.

#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

Varaktighet mellan två datetimes

Två datetimes t och u kan subtraheras med hjälp av t - u för att beräkna varaktigheten mellan dem. Här står datetime för någon av date, datetime, datetimezoneeller time. Varaktigheten som genereras genom att subtrahera u från t måste ge när t den läggs till ui .

#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

Subtrahera t - u när u > t resulterar i en negativ varaktighet:

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

Följande gäller när du subtraherar två datetimes med hjälp av t - u:

  • u + (t - u) = t

multiplikationsoperator

Tolkningen av multiplikationsoperatorn (x * y) är beroende av typen av värde för de utvärderade uttrycken x och y, enligt följande:

X Y Result Tolkning
type number type number type number Numerisk produkt
type number null null
null type number null
type duration type number type duration Flera varaktigheter
type number type duration type duration Flera varaktigheter
type duration null null
null type duration null

För andra kombinationer av värden än de som anges i tabellen genereras ett fel med orsakskoden "Expression.Error" . Varje kombination beskrivs i följande avsnitt.

Fel som uppstår vid utvärdering av någon av operanderna sprids.

Numerisk produkt

Produkten av två tal beräknas med hjälp av multiplikationsoperatorn och producerar ett tal. Till exempel:

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

Multiplikationsoperatorn * över tal använder dubbel precision. Standardbiblioteksfunktionen Value.Multiply kan användas för att ange decimalprecision. Följande gäller vid beräkning av en produkt med siffror:

  • Produkten i Dubbel precision beräknas enligt reglerna för 64-bitars binär dubbelprecision IEEE 754 aritmetik IEEE 754-2008. I följande tabell visas resultatet av alla möjliga kombinationer av icke-ändliga värden, nollor, infiniteter och NaN:er. I tabellen x och y är positiva ändliga värden. z är resultatet av x * y. Om resultatet är för stort för måltypen z är oändligheten. Om resultatet är för litet för måltypen z är det noll.

    * +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
  • Produkten i Decimalprecision beräknas utan att förlora precision. Resultatets skala är den större av de två operandernas skalor.

Multiplar av varaktigheter

Produkten av en varaktighet och ett tal är varaktigheten som representerar antalet 100nanosecond-tick som representeras av varaktigheten operand gånger talet operand. Till exempel:

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

divisionsoperator

Tolkningen av divisionsoperatorn (x / y) är beroende av typen av värde för de utvärderade uttrycken x och y, enligt följande:

X Y Result Tolkning
type number type number type number Numerisk kvot
type number null null
null type number null
type duration type number type duration Del av varaktigheten
type duration type duration type duration Numerisk kvot för varaktigheter
type duration null null
null type duration null

För andra kombinationer av värden än de som anges i tabellen genereras ett fel med orsakskoden "Expression.Error" . Varje kombination beskrivs i följande avsnitt.

Fel som uppstår vid utvärdering av någon av operanderna sprids.

Numerisk kvot

Kvoten för två tal beräknas med hjälp av divisionsoperatorn och genererar ett tal. Till exempel:

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

Divisionsoperatorn / över tal använder dubbel precision. Standardbiblioteksfunktionen Value.Divide kan användas för att ange decimalprecision. Följande gäller vid beräkning av en kvot med tal:

  • Kvoten i Dubbel precision beräknas enligt reglerna för 64-bitars binär dubbelprecision IEEE 754 aritmetik IEEE 754-2008. I följande tabell visas resultatet av alla möjliga kombinationer av icke-ändliga värden, nollor, infiniteter och NaN:er. I tabellen x och y är positiva ändliga värden. z är resultatet av x / y. Om resultatet är för stort för måltypen z är oändligheten. Om resultatet är för litet för måltypen z är det noll.

    / +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
  • Summan i decimalprecision beräknas utan att precisionen går förlorad. Resultatets skala är den större av de två operandernas skalor.

Varaktighetskvot

Kvoten för två varaktigheter är det tal som representerar kvoten för antalet tick på 100stinglar som representeras av varaktigheterna. Till exempel:

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

Skalbara varaktigheter

Kvoten för en varaktighet x och ett tal y är varaktigheten som representerar kvoten för antalet tick på 100 nanosekunder som representeras av varaktigheten x och talet y. Till exempel:

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

Strukturkombination

Kombinationsoperatorn (x & y) definieras över följande typer av värden:

X Y Result Tolkning
type text type text type text Sammanfogning
type text null null
null type text null
type date type time type datetime Slå ihop
type date null null
null type time null
type list type list type list Sammanfogning
type record type record type record Slå ihop
type table type table type table Sammanfogning

Sammanfogning

Två text-, två- eller två tabellvärden kan sammanfogas med hjälp av x & y.

I följande exempel visas sammanlänkning av textvärden:

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

I följande exempel visas sammanlänkningslistor:

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

Följande gäller vid sammanfogning av två värden med hjälp av x & y:

  • Fel som uppstår när du utvärderar x eller y uttryck sprids.

  • Inget fel sprids om ett objekt i något x av eller y innehåller ett fel.

  • Resultatet av att sammanfoga två textvärden är ett textvärde som innehåller värdet x omedelbart följt av y. Om någon av operanderna är null och den andra är ett textvärde är resultatet null.

  • Resultatet av att sammanfoga två listor är en lista som innehåller alla objekt x i följt av alla objekt yi .

  • Resultatet av att sammanfoga två tabeller är en tabell som har en union av de två operandtabellens kolumner. Kolumnordningen x för bevaras, följt av kolumnerna som endast visas i y, vilket bevarar deras relativa ordning. För kolumner som endast visas i en av operanderna null används för att fylla i cellvärden för den andra operanden.

Slå ihop

Sammanslagning av post

Två poster kan sammanfogas med hjälp av x & y, vilket skapar en post som innehåller fält från både x och y.

Följande exempel illustrerar sammanslagning av poster:

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

Följande gäller vid sammanslagning av två poster med hjälp av x + y:

  • Fel som uppstår när du utvärderar x eller y uttryck sprids.

  • Om ett fält visas i både x och yanvänds värdet från y .

  • Ordningen på fälten i den resulterande posten är , följt av xfält i y som inte är en del av x, i samma ordning som de visas i y.

  • Sammanslagning av poster orsakar inte utvärdering av värdena.

  • Inget fel utlöses eftersom ett fält innehåller ett fel.

  • Resultatet är en post.

Sammanslagning av datum och tid

Ett datum x kan sammanfogas med en tid y med hjälp av x & y, vilket skapar en datetime som kombinerar delarna från både x och y.

I följande exempel visas sammanslagning av ett datum och en tid:

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

Följande gäller vid sammanslagning av två poster med hjälp av x + y:

  • Fel som uppstår när du utvärderar x eller y uttryck sprids.

  • Resultatet är en datetime.

Unära operatorer

Operatorerna +, -och not är unary-operatorer.

unary-expression:
      type-expression

      +unary-uttryck
      -unary-uttryck
      notunary-uttryck

Unary plus-operator

Den unary plus-operatorn (+x) definieras för följande typer av värden:

X Result Tolkning
type number type number Unary plus
type duration type duration Unary plus
null 'null

För andra värden utlöses ett fel med orsakskoden "Expression.Error" .

Med operatorn unary plus kan ett + tecken tillämpas på ett tal, en datetime eller ett null-värde. Resultatet är samma värde. Till exempel:

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

Följande gäller vid utvärdering av unary plus-operatorn +x:

  • Fel som uppstår vid utvärdering x sprids.

  • Om resultatet av utvärderingen x inte är ett talvärde genereras ett fel med orsakskoden "Expression.Error" .

Unary minus operator

Unary minus-operatorn (-x) definieras för följande typer av värden:

X Result Tolkning
type number type number Negation
type duration type duration Negation
null null

För andra värden utlöses ett fel med orsakskoden "Expression.Error" .

Operatorn unary minus används för att ändra tecknet för ett tal eller en varaktighet. Till exempel:

- (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)

Följande gäller vid utvärdering av unary minus-operatorn -x:

  • Fel som uppstår vid utvärdering x sprids.

  • Om uttrycket är ett tal blir resultatet talvärdet från uttrycket x med dess tecken ändrat. Om värdet är NaN blir resultatet även NaN.

Logisk negationsoperator

Operatorn för logisk negation (not) definieras för följande typer av värden:

X Result Tolkning
type logical type logical Negation
null null

Den här operatorn beräknar den logiska not åtgärden för ett visst logiskt värde. Till exempel:

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

Följande gäller när du utvärderar operatorn not xför logisk negation :

  • Fel som uppstår vid utvärdering x sprids.

  • Värdet som genereras från utvärderingen av uttrycket x måste vara ett logiskt värde, eller så måste ett fel med orsakskoden "Expression.Error" genereras. Om värdet är trueär falseresultatet . Om operand är falseär trueresultatet .

Resultatet är ett logiskt värde.

Typoperatorer

Operatorerna is och as kallas typoperatorer.

Typkompatibilitetsoperator

Typkompatibilitetsoperatorn x is y definieras för följande typer av värden:

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

Uttrycket x is y returnerar true om den tillskrivna typen av x är kompatibel med yoch returnerar false om den tillskrivna typen av x är inkompatibel med y. y måste vara en nullable-primitivetype.

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

      nullableopt primitive-type

Typkompatibilitet, som stöds av operatornis, är en delmängd av allmän typkompatibilitet och definieras med hjälp av följande regler:

  • Om x är null är det kompatibelt om y är typen any, typen nulleller en nullbar typ.

  • Om x är icke-null så om det är en kompatibel om den primitiva typen av x är samma som y.

Följande gäller vid utvärdering av uttrycket x is y:

  • Ett fel som uppstår vid utvärdering av uttryck x sprids.

Typkontrolloperator

Typkontrolloperatorn x as y definieras för följande typer av värden:

X Y Result
type any nullable-primitive-type type any

Uttrycket x as y hävdar att värdet x är kompatibelt med y enligt operatorn is . Om det inte är kompatibelt utlöses ett fel. y måste vara en nullable-primitive-type.

as-expression:
      likhetsuttryck
      as-expression
as nullable-primitive-type

Uttrycket x as y utvärderas på följande sätt:

  • En typkompatibilitetskontroll x is y utförs och försäkran returnerar x oförändrad om testet lyckas.

  • Om kompatibilitetskontrollen misslyckas utlöses ett fel med orsakskoden "Expression.Error" .

Exempel:

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

Följande gäller vid utvärdering av uttrycket x as y:

  • Ett fel som uppstår vid utvärdering av uttryck x sprids.

Coalesce-operator

Kolesceoperatorn ?? returnerar resultatet av sin vänstra operand om den inte är null, annars returneras resultatet av dess högra operande. Den högra operanden utvärderas om och endast om den vänstra operanden är null.