Formazione
Modulo
Eseguire operazioni di base sui numeri in C# - Training
Informazioni sugli operatori e le tecniche usati per eseguire operazioni matematiche di base su dati numerici.
Questo browser non è più supportato.
Esegui l'aggiornamento a Microsoft Edge per sfruttare i vantaggi di funzionalità più recenti, aggiornamenti della sicurezza e supporto tecnico.
Questa sezione definisce il comportamento dei diversi operatori M.
Se un'espressione contiene più operatori, la precedenza degli operatori determina l'ordine in cui vengono valutati i singoli operatori. Ad esempio, l'espressione x + y * z
viene valutata come x + (y * z)
perché l'operatore *
ha la precedenza rispetto all'operatore +
binario. La precedenza di un operatore viene stabilita dalla definizione della produzione grammaticale associata. Un'additive-expression, ad esempio, è costituita da una sequenza di multiplicative-expression separate dagli operatori +
o -
, assegnando in questo modo una precedenza inferiore agli operatori +
e -
rispetto agli operatori *
e /
.
La produzione di parenthesized-expression può essere usata per modificare l'ordine di precedenza predefinito.
parenthesized-expression:
(
expression)
Ad esempio:
1 + 2 * 3 // 7
(1 + 2) * 3 // 9
La tabella seguente riepiloga gli operatori M, elencando le categorie di operatori in ordine di precedenza, dalla più alta alla più bassa. Gli operatori della stessa categoria hanno uguale precedenza.
Categoria | Expression | Descrizione |
---|---|---|
Primari |
i @ i |
Espressione identificatore |
(x) | Espressione racchiusa tra parentesi | |
x[i] | Cerca | |
x{y} | Accesso agli elementi | |
x(...) | Chiamata di funzione | |
{x, y, ...} | Inizializzazione elenco | |
[ i = x, ... ] | Inizializzazione del record | |
... | Non implementato | |
Unario | + x | Identità |
- x | Negazione | |
not
x |
Negazione logica | |
Metadati UFX |
xmeta y |
Associare i metadati |
Moltiplicazione | x * y | Moltiplicazione |
x / y | Divisione | |
Additive | x + y | Addizione |
x - y | Sottrazione | |
Relazionale | x< y | Minore di |
x > y | Maggiore di | |
x<= y | Minore di o uguale a | |
x >= y | Maggiore di o uguale a | |
Equality | x = y | Uguale |
x<> y | Not equal | |
Asserzione di tipo |
xas y |
Errore o tipo primitivo nullable compatibile |
Conformità del tipo |
xis y |
Testa se è un tipo primitivo nullable compatibile |
AND logico |
xand y |
Congiunzione di corto circuito |
OR logico |
xor y |
Disgiunzione di cortocircuito |
Coalesce |
x?? y |
Operatore di coalescenza di valori Null |
A ogni valore è associato un valore di record che può includere informazioni aggiuntive sul valore. Questo record è detto record di metadati per un valore. Un record di metadati può essere associato a qualsiasi tipo di valore, anche null
. Il risultato di tale associazione è un nuovo valore con i metadati specificati.
Un record di metadati è un normale record e può contenere qualsiasi campo e valore possa essere contenuto in un normale record e contenga a sua volta un record di metadati. L'associazione di un record di metadati a un valore è "non invasiva". Non comporta la modifica del comportamento del valore nelle valutazioni, a eccezione di quelle che ispezionano in modo esplicito i record di metadati.
Ogni valore ha un record di metadati predefinito, anche se non ne è stato specificato uno. Il record di metadati predefinito è vuoto. Gli esempi seguenti illustrano l'accesso al record di metadati di un valore di testo tramite la funzione della libreria standard Value.Metadata
:
Value.Metadata( "Mozart" ) // []
I record di metadati in genere non vengono conservati quando un valore viene usato con un operatore o una funzione che costruisce un nuovo valore. Ad esempio, se due valori di testo vengono concatenati tramite l'operatore &
, i metadati del valore di testo risultante sono un record vuoto []
. Le espressioni seguenti sono equivalenti:
"Amadeus " & ("Mozart" meta [ Rating = 5 ])
"Amadeus " & "Mozart"
È possibile usare le funzioni della libreria standard Value.RemoveMetadata
e Value.ReplaceMetadata
per rimuovere tutti i metadati da un valore e sostituire i metadati di un valore (invece di unire i metadati nei metadati eventualmente esistenti).
Il solo operatore che restituisce risultati contenenti metadati è l'operatore meta.
I valori possono essere ciclici, Ad esempio:
let l = {0, @l} in l
// {0, {0, {0, ... }}}
[A={B}, B={A}]
// [A = {{ ... }}, B = {{ ... }}]
M gestisce i valori ciclici mantenendo la costruzione di record, elenchi e tabelle lazy. Un tentativo di costruire un valore ciclico che non trae vantaggio dai valori strutturati lazy inseriti genera un errore:
[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"),
// ]
Alcuni operatori in M sono definiti dalla ricorsione strutturale. Ad esempio, l'uguaglianza di record ed elenchi è definita dall'uguaglianza congiunta dei campi di record e degli elenchi di elementi corrispondenti, rispettivamente.
Per i valori non ciclici, l'applicazione di una ricorsione strutturale genera un'espansione finita del valore: i valori annidati condivisi verranno attraversati ripetutamente, ma il processo di ricorsione termina sempre.
Un valore ciclico ha un'espansione infinita quando si applica una ricorsione strutturale. La semantica di M non prevede la presenza di tali espansioni infinite. Un tentativo di confrontare valori ciclici per verificarne l'uguaglianza, ad esempio, in genere esaurirà le risorse e verrà terminato con un'eccezione.
Gli operatori di selezione e proiezione consentono di estrarre i dati dai valori di elenco e di record.
Un valore può essere selezionato da un elenco o da una tabella a seconda della posizione in base zero all'interno di tale elenco o tabella usando un'espressione item-access-expression.
item-access-expression:
item-selection
optional-item-selection
item-selection:
primary-expression{
item-selector}
optional-item-selection:
primary-expression{
item-selector} ?
item-selector:
expression
L'espressione item-access-expressionx{y}
restituisce:
Per un elenco x
e un numero y
, l'elemento dell'elenco x
nella posizione y
. Si presuppone che il primo elemento di un elenco abbia un indice ordinale pari a zero. Se la posizione richiesta non esiste nell'elenco, viene generato un errore.
Per una tabella x
e un numero y
, la riga della tabella x
nella posizione y
. Si presuppone che la prima riga di una tabella abbia un indice ordinale pari a zero. Se la posizione richiesta non esiste nella tabella, viene generato un errore.
Per una tabella x
e un record y
, la riga della tabella x
che corrisponde ai valori di campo del record y
per i campi con nomi di campo che corrispondono ai relativi nomi delle colonne della tabella. Se nella tabella non è presente alcuna riga univoca corrispondente, viene generato un errore.
Ad esempio:
{"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 supporta anche la forma x{y}?
, che restituisce null
quando la posizione (o la corrispondenza) y
non esiste nell'elenco o nella tabella x
. Se sono presenti più corrispondenze per y
, viene comunque generato un errore.
Ad esempio:
{"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
L'accesso agli elementi non forza la valutazione di elementi dell'elenco o della tabella diversi da quello a cui si accede, Ad esempio:
{ error "a", 1, error "c"}{1} // 1
{ error "a", error "b"}{1} // error "b"
Quando viene valutato l'operatore di accesso all'elemento x{y}
, tenere presente quanto segue:
Gli errori generati durante la valutazione delle espressioni x
o y
vengono propagati.
L'espressione x
produce un elenco o un valore di tabella.
L'espressione y
produce un valore numerico o, se x
produce un valore di tabella, un valore di record.
Se y
produce un valore numerico e il valore di y
è negativo, viene generato un errore con il codice motivo "Expression.Error"
.
Se y
produce un valore numerico e il valore di y
è maggiore o uguale al conteggio di x
, viene generato un errore con il codice motivo "Expression.Error"
a meno che non venga usata la forma dell'operatore facoltativo x{y}?
, nel qual caso viene restituito il valore null
.
Se x
produce un valore di tabella e y
produce un valore di record e non sono presenti corrispondenze per y
in x
, viene generato un errore con il codice motivo "Expression.Error"
a meno che non venga usata la forma dell'operatore facoltativo x{y}?
, nel qual caso viene restituito il valore null
.
Se x
produce un valore di tabella e y
produce un valore di record e sono presenti più corrispondenze per y
in x
, viene generato un errore con il codice motivo "Expression.Error"
.
Nessun elemento in x
diverso da quello nella posizione y
viene valutato durante il processo di selezione dell'elemento. Per gli elenchi o le tabelle di flusso, gli elementi o le righe che lo precedono nella posizione y
vengono ignorati e possono quindi venire valutati, a seconda dell'origine dell'elenco o della tabella.
field-access-expression viene usata per selezionare un valore da un record o per proiettare un record o una tabella in una con meno campi o colonne, rispettivamente.
field-access-expression:
field-selection
implicit-target-field-selection
proiezione
implicit-target-projection
field-selection:
primary-expression field-selector
field-selector:
required-field-selector
optional-field-selector
required-field-selector:
[
field-name]
optional-field-selector:
[
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]
optional-projection:
[
required-selector-list] ?
required-selector-list:
required-field-selector
required-selector-list,
required-field-selector
implicit-target-projection:
required-projection
optional-projection
La forma più semplice di accesso a un campo è la selezione del campo obbligatoria, che usa l'operatore x[y]
per cercare un campo in un record in base al nome del campo. Se il campo y
non esiste in x
, viene generato un errore. La forma x[y]?
viene usata per eseguire la selezione del campo facoltativa e restituisce null
se il campo richiesto non esiste nel record.
Ad esempio:
[A=1,B=2][B] // 2
[A=1,B=2][C] // error
[A=1,B=2][C]? // null
L'accesso collettivo di più campi è supportato dagli operatori per la proiezione del record obbligatoria e la proiezione del record facoltativa. L'operatore x[[y1],[y2],...]
proietta il record in un nuovo record con meno campi (selezionati da y1
, y2
, ...
). Se un campo selezionato non esiste, viene generato un errore. L'operatore x[[y1],[y2],...]?
proietta il record in un nuovo record con i campi selezionati da y1
, y2
, ...
. Se un campo non è presente, viene usato null
,
Ad esempio:
[A=1,B=2][[B]] // [B=2]
[A=1,B=2][[C]] // error
[A=1,B=2][[B],[C]]? // [B=2,C=null]
Le forme [y]
e [y]?
sono supportate come riferimento di sintassi abbreviata all'identificatore _
(carattere di sottolineatura). Le due espressioni seguenti sono equivalenti:
[A]
_[A]
L'esempio seguente illustra la forma abbreviata di accesso ai campi:
let _ = [A=1,B=2] in [A] //1
Anche le forme [[y1],[y2],...]
e [[y1],[y2],...]?
sono supportate come sintassi abbreviata e anche le due espressioni seguenti sono equivalenti:
[[A],[B]]
_[[A],[B]]
La forma abbreviata è particolarmente utile in combinazione con la sintassi abbreviata each
, che consente di introdurre una funzione di un singolo parametro denominato _
. Per informazioni dettagliate, vedere Dichiarazioni semplificate. Insieme, le due sintassi abbreviate semplificano le espressioni funzionali comuni di ordine superiore:
List.Select( {[a=1, b=1], [a=2, b=4]}, each [a] = [b])
// {[a=1, b=1]}
L'espressione sopra indicata è equivalente alla sintassi estesa seguente più difficile da interpretare:
List.Select( {[a=1, b=1], [a=2, b=4]}, (_) => _[a] = _[b])
// {[a=1, b=1]}
L'accesso ai campi non forza la valutazione di campi diversi da quelli a cui si accede, Ad esempio:
[A=error "a", B=1, C=error "c"][B] // 1
[A=error "a", B=error "b"][B] // error "b"
Quando viene valutato l'operatore di accesso a un campo x[y]
, x[y]?
, x[[y]]
o x[[y]]?
, tenere presente quanto segue:
Gli errori generati durante la valutazione dell'espressione x
vengono propagati.
Gli errori generati durante la valutazione del campo y
sono associati in modo permanente al campo y
, quindi propagati. Eventuali accessi futuri al campo y
genereranno un errore identico.
L'espressione x
produce un valore di record o tabella oppure viene generato un errore.
Se l'identificatore y
denomina un campo che non esiste in x
, viene generato un errore con il codice motivo "Expression.Error"
a meno che non venga usata la forma dell'operatore facoltativo ...?
, nel qual caso viene restituito il valore null
.
Nessun campo di x
diverso da quello denominato da y
viene valutato durante il processo di accesso al campo.
Il record di metadati per un valore viene modificato usando l'operatore meta (x meta y
).
metadata-expression:
unary-expression
unary-expressionmeta
unary-expression
L'esempio seguente costruisce un valore di testo con un record di metadati usando l'operatore meta
e quindi accede al record di metadati del valore risultante usando Value.Metadata
:
Value.Metadata( "Mozart" meta [ Rating = 5 ] )
// [Rating = 5 ]
Value.Metadata( "Mozart" meta [ Rating = 5 ] )[Rating]
// 5
Quando si applicano i metadati che combinano l'operatore x meta y
, tenere presente quanto segue:
Gli errori generati durante la valutazione delle espressioni x
o y
vengono propagati.
L'espressione y
deve essere un record, altrimenti viene generato un errore con il codice motivo "Expression.Error"
.
Il record di metadati risultante è il record di metadati di x
unito con y
. Per la semantica del merge di record, vedere Unione di record.
Il valore risultante è il valore dell'espressione x
, senza i metadati, a cui è collegato il record di metadati appena calcolato.
È possibile usare le funzioni della libreria standard Value.RemoveMetadata
e Value.ReplaceMetadata
per rimuovere tutti i metadati da un valore e sostituire i metadati di un valore (invece di unire i metadati nei metadati eventualmente esistenti). Le espressioni seguenti sono equivalenti:
x meta y
Value.ReplaceMetadata(x, Value.Metadata(x) & y)
Value.RemoveMetadata(x) meta (Value.Metadata(x) & y)
L'operatore di uguaglianza=
viene usato per determinare se due valori sono uguali. L'operatore di disuguaglianza<>
viene usato per determinare se due valori non sono uguali.
equality-expression:
relational-expression
relational-expression=
equality-expression
relational-expression<>
equality-expression
Ad esempio:
1 = 1 // true
1 = 2 // false
1 <> 1 // false
1 <> 2 // true
null = true // false
null = null // true
I metadati non fanno parte del confronto di uguaglianza o disuguaglianza, Ad esempio:
(1 meta [ a = 1 ]) = (1 meta [ a = 2 ]) // true
(1 meta [ a = 1 ]) = 1 // true
Quando si applicano gli operatori di uguaglianza x = y
e x <> y
, tenere presente quanto segue:
Gli errori generati durante la valutazione delle espressioni x
o y
vengono propagati.
L'operatore =
ha come risultato true
se i valori sono uguali; in caso contrario, false
.
L'operatore <>
ha come risultato false
se i valori sono uguali; in caso contrario, true
.
I record di metadati non sono inclusi nel confronto.
Se i valori prodotti dalla valutazione delle espressioni x
e y
non sono dello stesso tipo, i valori non sono uguali.
Se i valori prodotti dalla valutazione delle espressioni x
e y
sono dello stesso tipo, esistono regole specifiche per determinare se sono uguali, come definito di seguito.
La formula seguente è sempre vera:
(x = y) = not (x <> y)
Gli operatori di uguaglianza sono definiti per i tipi seguenti:
null
è uguale solo a se stesso. null = null // true
null = true // false
null = false // false
true
e false
sono uguali a se stessi, Ad esempio: true = true // true
false = false // true
true = false // false
true = 1 // false
I numeri vengono confrontati con la precisione specificata:
Se uno dei due numeri è #nan
, i numeri non sono uguali.
Quando nessuno dei due numeri è #nan
, i numeri vengono confrontati usando un confronto bit per bit del valore numerico.
#nan
è l'unico valore non uguale a se stesso.
Ad esempio:
1 = 1, // true
1.0 = 1 // true
2 = 1 // false
#nan = #nan // false
#nan <> #nan // true
Due durate sono uguali se rappresentano lo stesso numero di cicli da 100 nanosecondi.
Due ore sono uguali se gli ordini di grandezza delle parti (ora, minuto, secondo) sono uguali.
Due date sono uguali se gli ordini di grandezza delle parti (anno, mese, giorno) sono uguali.
Due valori di data/ora sono uguali se gli ordini di grandezza delle parti (anno, mese, giorno, ora, minuto, secondo) sono uguali.
Due fusi orari sono uguali se i valori di data/ora UTC corrispondenti sono uguali. Per ottenere la data/ora UTC corrispondente, l'offset di ore/minuti viene sottratto dal componente data/ora del fuso orario.
Due valori di testo sono uguali se, usando un confronto ordinale, con distinzione tra maiuscole e minuscole e senza distinzione di impostazioni cultura, hanno la stessa lunghezza e caratteri uguali nelle posizioni corrispondenti.
Due valori di elenco sono uguali se si verificano tutte le condizioni seguenti:
Entrambi gli elenchi contengono lo stesso numero di elementi.
I valori di ogni elemento corrispondente a livello di posizione negli elenchi sono uguali. Ciò significa che non solo gli elenchi devono contenere elementi uguali, ma gli elementi devono anche essere nello stesso ordine.
Ad esempio:
{1, 2} = {1, 2} // true
{2, 1} = {1, 2} // false
{1, 2, 3} = {1, 2} // false
Due record sono uguali se si verificano tutte le condizioni seguenti:
Il numero di campi è lo stesso.
Ogni nome di campo di un record è presente anche nell'altro record.
Il valore di ogni campo di un record è uguale al campo con lo stesso nome nell'altro record.
Ad esempio:
[ 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
Due tabelle sono uguali se si verificano tutte le condizioni seguenti:
Il numero di colonne è lo stesso.
Ogni nome di colonna in una tabella è presente anche nell'altra tabella.
Il numero di righe è lo stesso.
Ogni riga ha valori uguali nelle celle corrispondenti.
Ad esempio:
#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
Un valore di funzione è uguale a se stesso, ma può essere uguale o meno a un altro valore di funzione. Se due valori di funzione sono considerati uguali, si comporteranno in modo identico quando vengono richiamati.
Due valori di funzione specificati avranno sempre la stessa relazione di uguaglianza.
Un valore di tipo è uguale a se stesso, ma può essere uguale o meno a un altro valore di tipo. Se due valori di tipo sono considerati uguali, si comporteranno in modo identico quando ne viene verificata la conformità tramite query.
Due valori di tipo specificati avranno sempre la stessa relazione di uguaglianza.
Gli operatori <
, >
, <=
e >=
sono detti operatori relazionali.
relational-expression:
additive-expression
additive-expression<
relational-expression
additive-expression>
relational-expression
additive-expression<=
relational-expression
additive-expression>=
relational-expression
Questi operatori vengono usati per determinare la relazione di ordinamento relativa tra due valori, come illustrato nella tabella seguente:
Operazione | Risultato |
---|---|
x < y |
true se x è minore di y ; in caso contrario, false |
x > y |
true se x è maggiore di y ; in caso contrario, false |
x <= y |
true se x è minore o uguale a y ; in caso contrario, false |
x >= y |
true se x è maggiore o uguale a y ; in caso contrario, false |
Ad esempio:
0 <= 1 // true
null < 1 // null
null <= null // null
"ab" < "abc" // true
#nan >= #nan // false
#nan <= #nan // false
Quando si valuta un'espressione contenente gli operatori relazionali, tenere presente quanto segue:
Gli errori generati durante la valutazione delle espressioni dell'operando x
o y
vengono propagati.
I valori prodotti dalla valutazione di entrambe le espressioni x
e y
devono essere un valore binario, data, data/ora, fuso orario, durata, logico, numero, null, testo o ora. In caso contrario, viene generato un errore con il codice motivo "Expression.Error"
.
Entrambi gli operandi devono essere dello stesso tipo di valore o null
. In caso contrario, viene generato un errore con il codice motivo "Expression.Error"
.
Se uno o entrambi gli operandi sono null
, il risultato è il valore null
.
Due file binari vengono confrontati byte per byte.
Due date vengono confrontate confrontando le parti degli anni e, se uguali, le parti dei mesi e, se uguali, le parti dei giorni.
Due valori di data/ora vengono confrontati confrontando le parti degli anni e, se uguali, le parti dei mesi e, se uguali, le parti dei giorni e, se uguali, le parti delle ore e, se uguali, le parti dei minuti e, se uguali, le parti dei secondi.
Due fusi orari vengono confrontati normalizzandoli in UTC sottraendo l'offset di ora/minuto e confrontando quindi i componenti di data/ora.
Due durate vengono confrontate in base al numero totale di cicli da 100 nanosecondi rappresentato.
Due logiche vengono confrontate in modo che true
sia considerato maggiore di false
.
Due numeri x
e y
vengono confrontati in base alle regole dello standard IEEE 754:
Se uno degli operandi è #nan
, il risultato è false
per tutti gli operatori relazionali.
Quando nessuno degli operandi è #nan
, gli operatori confrontano i valori dei due operandi a virgola mobile rispetto all'ordinamento -∞ < -max < ... < -min < -0.0 = +0.0 < +min < ... < +max < +∞
dove min e max sono i valori finiti positivi più piccoli e più grandi che possono essere rappresentati. I nomi M per -∞ e +∞ sono -#infinity
e #infinity
.
Gli effetti più importanti di questo ordinamento sono:
Gli zeri negativi e positivi sono considerati uguali.
Un valore -#infinity
è considerato minore di tutti gli altri valori numerici, ma uguale a un altro -#infinity
.
Un valore #infinity
è considerato maggiore di tutti gli altri valori numerici, ma uguale a un altro #infinity
.
Due testi vengono confrontati usando un confronto ordinale carattere per carattere, con distinzione tra maiuscole e minuscole e senza distinzione tra impostazioni cultura.
Due ore vengono confrontate confrontando le parti delle ore e, se uguali, le parti dei minuti e, se uguali, le parti dei secondi.
Gli operatori and
e or
sono detti operatori logici condizionali.
logical-or-expression:
logical-and-expression
logical-and-expressionor
logical-or-expression
logical-and-expression:
is-expression
is-expressionand
logical-and-expression
L'operatore or
restituisce true
quando almeno uno degli operandi è true
. L'operando di destra viene valutato solo se l'operando di sinistra non è true
.
L'operatore and
restituisce false
quando almeno uno degli operandi è false
. L'operando di destra viene valutato solo se l'operando di sinistra non è false
.
Le tabelle di veridicità per gli operatori or
e and
sono illustrate di seguito, con il risultato della valutazione dell'espressione dell'operando di sinistra sull'asse verticale e il risultato della valutazione dell'espressione dell'operando di destra sull'asse orizzontale.
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 |
Quando si valuta un'espressione contenente gli operatori logici condizionali, tenere presente quanto segue:
Gli errori generati durante la valutazione delle espressioni x
o y
vengono propagati.
Gli operatori logici condizionali vengono definiti sui tipi logical
e null
. Se i valori degli operandi non sono di tali tipi, viene generato un errore con il codice motivo "Expression.Error"
.
Il risultato è un valore logico.
Nell'espressione x
o y
l'espressione y
verrà valutata solo se x
non restituisce true
.
Nell'espressione x
e y
l'espressione y
verrà valutata solo se x
non restituisce false
.
Le ultime due proprietà assegnano agli operatori logici condizionali la qualifica di "condizionale". Le proprietà vengono definite anche di "corto circuito". Queste proprietà sono utili per scrivere predicati controllati compatti. Le espressioni seguenti, ad esempio, sono equivalenti:
d <> 0 and n/d > 1 if d <> 0 then n/d > 1 else false
Gli operatori +
, -
, *
e /
sono gli operatori aritmetici.
additive-expression:
multiplicative-expression
additive-expression+
multiplicative-expression
additive-expression-
multiplicative-expression
multiplicative-expression:
metadata-expression
multiplicative-expression*
metadata-expression
multiplicative-expression/
metadata-expression
I numeri in M vengono archiviati usando diverse rappresentazioni per conservare il maggior numero possibile di informazioni sui numeri provenienti da svariate origini. I numeri vengono solo convertiti da una rappresentazione a un'altra in base alle esigenze tramite gli operatori applicati. Sono supportate due precisioni in M:
Precision | semantica |
---|---|
Precision.Decimal |
Rappresentazione decimale a 128 bit con un intervallo compreso tra ±1.0 x 10-28 e ±7.9 x 1028 e 28-29 cifre significative. |
Precision.Double |
Rappresentazione scientifica con mantissa ed esponente, conforme allo standard aritmetico IEEE 754 a precisione doppia a 64 bit IEEE 754-2008. |
Le operazioni aritmetiche vengono eseguite scegliendo una precisione, convertendo entrambi gli operandi in tale precisione (se necessario), quindi eseguendo l'operazione effettiva e infine restituendo un numero nella precisione scelta.
Gli operatori aritmetici predefiniti (+
, -
, *
, /
) usano la precisione doppia. È possibile usare le funzioni della libreria standard (Value.Add
, Value.Subtract
, Value.Multiply
, Value.Divide
) per richiedere queste operazioni usando un modello di precisione specifico.
Nessun overflow numerico è possibile: #infinity
o -#infinity
rappresentano valori di ordini di grandezza troppo elevati per essere rappresentati.
Nessun underflow numerico è possibile: 0
e -0
rappresentano valori di ordini di grandezza troppo piccoli per essere rappresentati.
Il valore speciale IEEE 754 #nan
(NaN, non un numero) viene usato per i casi aritmeticamente non validi, ad esempio una divisione di zero per zero.
La conversione da precisione decimale a doppia viene eseguita arrotondando i numeri decimali al valore doppio equivalente più vicino.
La conversione da precisione doppia a decimale viene eseguita arrotondando i numeri doppi al valore decimale equivalente più vicino e, se necessario, tramite overflow ai valori #infinity
o -#infinity
.
L'interpretazione dell'operatore di addizione (x + y
) dipende dal tipo di valore delle espressioni x e y valutate, come indicato di seguito:
x | y | Risultato | Interpretazione |
---|---|---|---|
type number |
type number |
type number |
Somma numerica |
type number |
null |
null |
|
null |
type number |
null |
|
type duration |
type duration |
type duration |
Somma numerica degli ordini di grandezza |
type duration |
null |
null |
|
null |
type duration |
null |
|
type
datetime |
type duration |
type
datetime |
Offset di datetime in base alla durata |
type duration |
type
datetime |
type
datetime |
|
type
datetime |
null |
null |
|
null |
type
datetime |
null |
Nella tabella type
datetime sta per qualsiasi type date
, type datetime
, type datetimezone
, o type time
. Quando si aggiungono una durata e un valore di un tipo datetime, il valore risultante è dello stesso tipo.
Per combinazioni di valori diverse da quelle elencate nella tabella, viene generato un errore con il codice motivo "Expression.Error"
. Ogni combinazione viene trattata nelle sezioni seguenti.
Gli errori generati durante la valutazione di uno degli operandi vengono propagati.
La somma di due numeri viene calcolata usando l'operatore di addizione, che produce un numero.
Ad esempio:
1 + 1 // 2
#nan + #infinity // #nan
L'operatore di addizione +
sui numeri usa la precisione doppia. La funzione della libreria standard Value.Add
può essere usata per specificare la precisione decimale. Quando si calcola una somma di numeri, tenere presente quanto segue:
La somma a precisione doppia viene calcolata in base alle regole aritmetiche IEEE 754 a precisione doppia binarie a 64 bit IEEE 754-2008. La tabella seguente elenca i risultati di tutte le possibili combinazioni di valori finiti diversi da zero, zeri, infiniti e non numeri. Nella tabella x
e y
sono valori finiti diversi da zero e z
è il risultato di x + y
. Se x
e y
hanno lo stesso ordine di grandezza ma segni opposti, z
è zero positivo. Se x + y
è troppo grande per essere rappresentato nel tipo di destinazione, z
è un valore infinito con lo stesso segno di 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 |
La somma a precisione decimale viene calcolata senza perdere la precisione. La scala del risultato è la più grande tra le scale dei due operandi.
La somma di due durate è la durata che rappresenta la somma del numero di cicli da 100 nanosecondi rappresentati dalle durate, Ad esempio:
#duration(2,1,0,15.1) + #duration(0,1,30,45.3)
// #duration(2, 2, 31, 0.4)
Un valore datetimex
e una durata y
possono essere sommati usando x + y
per calcolare un nuovo valore datetime la cui distanza da x
su una sequenza temporale lineare è esattamente l'ordine di grandezza di y
. In questo caso datetime sta per Date
, DateTime
, DateTimeZone
o Time
e un risultato non Null sarà dello stesso tipo. L'offset di datetime in base alla durata può essere calcolato come segue:
Se vengono specificati i giorni di datetime a partire dal valore di periodo, costruire un nuovo valore datetime con le informazioni seguenti:
Calcolare un nuovo valore "giorni dal periodo" equivalente alla divisione della grandezza di y per il numero di cicli da 100 nanosecondi in un periodo di 24 ore, troncando la parte decimale del risultato e aggiungendo questo valore ai giorni di x dal periodo.
Calcolare un nuovo valore "cicli da mezzanotte" equivalente all'aggiunta della grandezza di y ai cicli di x da mezzanotte, eseguendo il modulo del numero di cicli da 100 nanosecondi in un periodo di 24 ore. Se x non specifica un valore per i cicli dalla mezzanotte, si presume un valore pari a 0.
Copiare il valore di x per l'offset dei minuti dall'ora UTC non modificata.
Se non vengono specificati i giorni di datetime a partire dal valore di periodo, costruire un nuovo valore datetime con le informazioni seguenti specificate:
Calcolare un nuovo valore "cicli da mezzanotte" equivalente all'aggiunta della grandezza di y ai cicli di x da mezzanotte, eseguendo il modulo del numero di cicli da 100 nanosecondi in un periodo di 24 ore. Se x non specifica un valore per i cicli dalla mezzanotte, si presume un valore pari a 0.
Copiare i valori di x per i giorni dal periodo e l'offset dei minuti dall'ora UTC non modificata.
Gli esempi seguenti illustrano il calcolo della somma temporale assoluta quando datetime specifica i giorni dal periodo:
#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
L'esempio seguente illustra il calcolo dell'offset di datetime in base alla durata per un determinato periodo di tempo:
#time(8,0,0) + #duration(30,5,0,0)
//#time(13, 0, 0)
//13:00:00
L'interpretazione dell'operatore di sottrazione (x - y
) dipende dal tipo del valore delle espressioni x
e y
valutate, come indicato di seguito:
x | Y | Risultato | Interpretazione |
---|---|---|---|
type number |
type number |
type number |
Differenza numerica |
type number |
null |
null |
|
null |
type number |
null |
|
type duration |
type duration |
type duration |
Differenza numerica degli ordini di grandezze |
type duration |
null |
null |
|
null |
type duration |
null |
|
type
datetime |
type
datetime |
type duration |
Durata tra valori datetime |
type
datetime |
type duration |
type
datetime |
Offset di datetime in base alla durata negata |
type
datetime |
null |
null |
|
null |
type
datetime |
null |
Nella tabella type
datetime sta per qualsiasi type date
, type datetime
, type datetimezone
, o type time
. Quando si sottrae una durata da un valore di un tipo datetime, il valore risultante è dello stesso tipo.
Per combinazioni di valori diverse da quelle elencate nella tabella, viene generato un errore con il codice motivo "Expression.Error"
. Ogni combinazione viene trattata nelle sezioni seguenti.
Gli errori generati durante la valutazione di uno degli operandi vengono propagati.
La differenza tra due numeri viene calcolata usando l'operatore di sottrazione, che produce un numero. Ad esempio:
1 - 1 // 0
#nan - #infinity // #nan
L'operatore di sottrazione -
sui numeri usa la precisione doppia. La funzione della libreria standard Value.Subtract
può essere usata per specificare la precisione decimale. Quando si calcola una differenza tra numeri, tenere presente quanto segue:
La differenza a precisione doppia viene calcolata in base alle regole aritmetiche IEEE 754 a precisione doppia binarie a 64 bit IEEE 754-2008. La tabella seguente elenca i risultati di tutte le possibili combinazioni di valori finiti diversi da zero, zeri, infiniti e non numeri. Nella tabella x
e y
sono valori finiti diversi da zero e z
è il risultato di x - y
. Se x
e y
sono uguali, z
è zero positivo. Se x - y
è troppo grande per essere rappresentato nel tipo di destinazione, z
è un valore infinito con lo stesso segno di 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 |
La differenza a precisione decimale viene calcolata senza perdere la precisione. La scala del risultato è la più grande tra le scale dei due operandi.
La differenza di due durate è la durata che rappresenta la differenza tra il numero di cicli da 100 nanosecondi rappresentati da ogni durata, Ad esempio:
#duration(1,2,30,0) - #duration(0,0,0,30.45)
// #duration(1, 2, 29, 29.55)
Un valore datetimex
e una durata y
possono essere sottratti usando x - y
per calcolare un nuovo valore datetime. In questo caso datetime sta per date
, datetime
, datetimezone
o time
. Il valore datetime risultante ha una distanza da x
su una sequenza temporale lineare che corrisponde esattamente alla grandezza di y
, nella direzione opposta al segno di y
. La sottrazione di durate positive produce risultati che tornano indietro nel tempo relativamente a x
, mentre la sottrazione di valori negativi produce risultati che vanno avanti nel tempo.
#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
È possibile sottrarre due valori datetimet
e u
usando t - u
per calcolare la durata tra di essi. In questo caso datetime sta per date
, datetime
, datetimezone
o time
. La durata ottenuta sottraendo u
da t
deve restituire t
se aggiunta a u
.
#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
La sottrazione t - u
quando u > t
restituisce una durata negativa:
#time(01,30,00) - #time(08,00,00)
// #duration(0, -6, -30, 0)
Quando si sottraggono due valori datetime usando t - u
, tenere presente quanto segue:
L'interpretazione dell'operatore di moltiplicazione (x * y
) dipende dal tipo di valore delle espressioni x e y valutate, come indicato di seguito:
X | Y | Risultato | Interpretazione |
---|---|---|---|
type number |
type number |
type number |
Prodotto numerico |
type number |
null |
null |
|
null |
type number |
null |
|
type duration |
type number |
type duration |
Multiplo della durata |
type number |
type duration |
type duration |
Multiplo della durata |
type duration |
null |
null |
|
null |
type duration |
null |
Per combinazioni di valori diverse da quelle elencate nella tabella, viene generato un errore con il codice motivo "Expression.Error"
. Ogni combinazione viene trattata nelle sezioni seguenti.
Gli errori generati durante la valutazione di uno degli operandi vengono propagati.
Il prodotto di due numeri viene calcolato usando l'operatore di moltiplicazione, che produce un numero. Ad esempio:
2 * 4 // 8
6 * null // null
#nan * #infinity // #nan
L'operatore di moltiplicazione *
sui numeri usa la precisione doppia. La funzione della libreria standard Value.Multiply
può essere usata per specificare la precisione decimale. Quando si calcola un prodotto di numeri, tenere presente quanto segue:
Il prodotto a precisione doppia viene calcolato in base alle regole aritmetiche IEEE 754 a precisione doppia binarie a 64 bit IEEE 754-2008. La tabella seguente elenca i risultati di tutte le possibili combinazioni di valori finiti diversi da zero, zeri, infiniti e non numeri. Nella tabella x
e y
sono valori finiti positivi.
z
è il risultato di x * y
. Se il risultato è troppo grande per il tipo di destinazione, z
è infinito. Se il risultato è troppo piccolo per il tipo di destinazione, z
è pari a zero.
* | +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 |
Il prodotto a precisione decimale viene calcolato senza perdere la precisione. La scala del risultato è la più grande tra le scale dei due operandi.
Il prodotto di una durata e di un numero è uguale alla durata che rappresenta il numero di cicli da 100 nanosecondi rappresentati dall'operando della durata moltiplicato per l'operando del numero, Ad esempio:
#duration(2,1,0,15.1) * 2
// #duration(4, 2, 0, 30.2)
L'interpretazione dell'operatore di divisione (x / y
) dipende dal tipo di valore delle espressioni x
e y
valutate, come indicato di seguito:
X | Y | Risultato | Interpretazione |
---|---|---|---|
type number |
type number |
type number |
Quoziente numerico |
type number |
null |
null |
|
null |
type number |
null |
|
type duration |
type number |
type duration |
Frazione di durata |
type duration |
type duration |
type number |
Quoziente numerico delle durate |
type duration |
null |
null |
|
null |
type duration |
null |
Per combinazioni di valori diverse da quelle elencate nella tabella, viene generato un errore con il codice motivo "Expression.Error"
. Ogni combinazione viene trattata nelle sezioni seguenti.
Gli errori generati durante la valutazione di uno degli operandi vengono propagati.
Il quoziente di due numeri viene calcolato usando l'operatore di divisione, che produce un numero, Ad esempio:
8 / 2 // 4
8 / 0 // #infinity
0 / 0 // #nan
0 / null // null
#nan / #infinity // #nan
L'operatore di divisione /
sui numeri usa la precisione doppia. La funzione della libreria standard Value.Divide
può essere usata per specificare la precisione decimale. Quando si calcola un quoziente di numeri, tenere presente quanto segue:
Il quoziente a precisione doppia viene calcolato in base alle regole aritmetiche IEEE 754 a precisione doppia binarie a 64 bit IEEE 754-2008. La tabella seguente elenca i risultati di tutte le possibili combinazioni di valori finiti diversi da zero, zeri, infiniti e non numeri. Nella tabella x
e y
sono valori finiti positivi.
z
è il risultato di x / y
. Se il risultato è troppo grande per il tipo di destinazione, z
è infinito. Se il risultato è troppo piccolo per il tipo di destinazione, z
è pari a zero.
/ | +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 |
La somma a precisione decimale viene calcolata senza perdere la precisione. La scala del risultato è la più grande tra le scale dei due operandi.
Il quoziente di due durate è il numero che rappresenta il quoziente del numero di cicli da 100 nanosecondi rappresentati dalle durate, Ad esempio:
#duration(2,0,0,0) / #duration(0,1,30,0)
// 32
Il quoziente di una durata x
e di un numero y
è uguale alla durata che rappresenta il quoziente del numero di cicli da 100 nanosecondi rappresentati dalla durata x
e dal numero y
, Ad esempio:
#duration(2,0,0,0) / 32
// #duration(0,1,30,0)
L'operatore di combinazione (x & y
) viene definito nei tipi di valori seguenti:
X | Y | Risultato | Interpretazione |
---|---|---|---|
type text |
type text |
type text |
Concatenation |
type text |
null |
null |
|
null |
type text |
null |
|
type date |
type time |
type datetime |
Unire |
type date |
null |
null |
|
null |
type time |
null |
|
type list |
type list |
type list |
Concatenation |
type record |
type record |
type record |
Unire |
type table |
type table |
type table |
Concatenation |
Due valori di testo, due valori di elenco o due valori di tabelle possono essere concatenati usando x & y
.
L'esempio seguente illustra la concatenazione di valori di testo:
"AB" & "CDE" // "ABCDE"
L'esempio seguente illustra la concatenazione di elenchi:
{1, 2} & {3} // {1, 2, 3}
Quando si concatenano due valori usando x & y
, tenere presente quanto segue:
Gli errori generati durante la valutazione delle espressioni x
o y
vengono propagati.
Se un elemento di x
o y
contiene un errore, non viene propagato alcun errore.
Il risultato della concatenazione di due valori di testo è un valore di testo che contiene il valore di x seguito immediatamente da y. Se uno degli operandi è Null e l'altro è un valore di testo, il risultato è Null.
Il risultato della concatenazione di due elenchi è un elenco che contiene tutti gli elementi di x
seguiti da tutti gli elementi di y
.
Il risultato della concatenazione di due tabelle è una tabella che contiene l'unione delle colonne delle due tabelle dell'operando. L'ordinamento delle colonne di x
viene mantenuto, seguito dalle colonne visualizzate solo in y
, che mantengono il proprio ordinamento relativo. Per le colonne visualizzate solo in uno degli operandi, viene usato null
per inserire i valori delle celle per l'altro operando.
È possibile unire due record usando x & y
, che produce un record che include i campi sia di x
che di y
.
Gli esempi seguenti illustrano l'unione di record:
[ x = 1 ] & [ y = 2 ] // [ x = 1, y = 2 ]
[ x = 1, y = 2 ] & [ x = 3, z = 4 ] // [ x = 3, y = 2, z = 4 ]
Quando si uniscono due record usando x + y
, tenere presente quanto segue:
Gli errori generati durante la valutazione delle espressioni x
o y
vengono propagati.
Se un campo viene visualizzato sia in x
che in y
, viene usato il valore di y
.
L'ordine dei campi nel record risultante è quello di x
, seguiti dai campi di y
che non fanno parte di x
, nello stesso ordine in cui vengono visualizzati in y
.
L'unione di record non comporta la valutazione dei valori.
Non vengono generati errori perché un campo contiene un errore.
Il risultato è un record.
Una data x
può essere unita a un'ora y
usando x & y
, che produce un valore datetime che combina le parti sia di x
che di y
.
L'esempio seguente illustra l'unione di una data e di un'ora:
#date(2013,02,26) & #time(09,17,00)
// #datetime(2013,02,26,09,17,00)
Quando si uniscono due record usando x + y
, tenere presente quanto segue:
Gli errori generati durante la valutazione delle espressioni x
o y
vengono propagati.
Il risultato è un valore datetime.
Gli operatori +
, -
e not
sono operatori unari.
unary-expression:
type-expression
+
unary expression
-
unary expression
not
unary expression
L'operatore unario più (+x
) viene definito per i tipi di valori seguenti:
X | Risultato | Interpretazione |
---|---|---|
type number |
type number |
Più unario |
type duration |
type duration |
Più unario |
null |
`null |
Per gli altri valori, viene generato un errore con il codice motivo "Expression.Error"
.
L'operatore unario più consente di applicare un segno +
a un numero, a un valore datetime o a un valore Null. Il risultato è quello stesso valore, Ad esempio:
+ - 1 // -1
+ + 1 // 1
+ #nan // #nan
+ #duration(0,1,30,0) // #duration(0,1,30,0)
Quando si valuta l'operatore unario più +x
, tenere presente quanto segue:
Gli errori generati durante la valutazione di x
vengono propagati.
Se il risultato della valutazione di x
non è un valore numerico, viene generato un errore con il codice motivo "Expression.Error"
.
L'operatore unario meno (-x
) viene definito per i tipi di valori seguenti:
X | Risultato | Interpretazione |
---|---|---|
type number |
type number |
Negazione |
type duration |
type duration |
Negazione |
null |
null |
Per gli altri valori, viene generato un errore con il codice motivo "Expression.Error"
.
L'operatore unario meno viene usato per cambiare il segno di un numero o di una durata, Ad esempio:
- (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)
Quando si valuta l'operatore unario meno -x
, tenere presente quanto segue:
Gli errori generati durante la valutazione di x
vengono propagati.
Se l'espressione è un numero, il risultato è il valore numerico dell'espressione x
con il segno cambiato. Se il valore non è un numero, neanche il risultato è un numero.
L'operatore di negazione logica (not
) viene definito per i tipi di valori seguenti:
X | Risultato | Interpretazione |
---|---|---|
type logical |
type logical |
Negazione |
null |
null |
Questo operatore calcola l'operazione not
logica su un valore logico specificato, Ad esempio:
not true // false
not false // true
not (true and true) // false
Quando si valuta l'operatore di negazione logica not x
, tenere presente quanto segue:
Gli errori generati durante la valutazione di x
vengono propagati.
Il valore prodotto dalla valutazione dell'espressione x deve essere un valore logico oppure deve essere generato un errore con il codice motivo "Expression.Error"
. Se il valore è true
, il risultato è false
. Se l'operando è false
, il risultato è true
.
Il risultato è un valore logico.
Gli operatori is
e as
sono noti come operatori di tipo.
L'operatore di compatibilità del tipo x is y
è definito per i tipi di valori seguenti:
X | Y | Risultato |
---|---|---|
type any |
nullable-primitive-type | type logical |
L'espressione x is y
restituisce true
se il tipo ascritto di x
è compatibile con y
e restituisce false
se il tipo ascritto di x
non è compatibile con y
.
y
deve essere un tipo nullable-primitivetype.
is-expression:
as-expression
is-expressionis
nullable-primitive-type
nullable-primitive-type:
nullable
opt primitive-type
La compatibilità del tipo, supportata dall'operatore is
, è un subset della compatibilità del tipo generale e viene definita usando le regole seguenti:
Se x
è Null, è compatibile se y
è il tipo any
, il tipo null
o un tipo nullable.
Se x
è diverso da Null, è compatibile se il tipo primitivo di x
è lo stesso di y
.
Quando si valuta l'espressione x is y
, tenere presente quanto segue:
x
viene propagato.L'operatore di asserzione del tipo x as y
è definito per i tipi di valori seguenti:
X | Y | Risultato |
---|---|---|
type any |
nullable-primitive-type | type any |
L'espressione x as y
asserisce che il valore x
è compatibile con y
in base all'operatore is
. Se non è compatibile, viene generato un errore.
y
deve essere un tipo nullable-primitive-type.
as-expression:
equality-expression
as-expressionas
nullable-primitive-type
L'espressione x as y
viene valutata nel modo seguente:
Viene eseguita una verifica della compatibilità del tipo x is y
e l'asserzione restituisce x
non modificato se il test ha esito positivo.
Se la verifica della compatibilità ha esito negativo, viene generato un errore con il codice motivo "Expression.Error"
.
Esempi:
1 as number // 1
"A" as number // error
null as nullable number // null
Quando si valuta l'espressione x as y
, tenere presente quanto segue:
x
viene propagato.L'operatore coalesce ??
restituisce il risultato dell'operando sinistro se non è Null; in caso contrario, restituirà il risultato dell'operando destro. L'operando di destra viene valutato solo se l'operando di sinistra è null.
Formazione
Modulo
Eseguire operazioni di base sui numeri in C# - Training
Informazioni sugli operatori e le tecniche usati per eseguire operazioni matematiche di base su dati numerici.