Coercizione mediante gli operatori bit per bit
Gli operatori bit per bit disponibili in questa versione di JScript sono pienamente compatibili con quelli utilizzati nelle precedenti versioni. Inoltre, gli operatori JScript possono anche essere utilizzati con i nuovi tipi di dati numerici. Poiché il loro funzionamento dipende dalla rappresentazione binaria dei dati, è importante comprendere le modalità di coercizione del tipo di dati da parte degli operatori.
Agli operatori bit per bit possono essere passati tre tipi di argomenti: variabili associate anticipatamente, variabili associate tardivamente e dati letterali. Le variabili associate anticipatamente sono variabili definite mediante un'annotazione del tipo esplicita. Le variabili associate tardivamente sono variabili di tipo Object contenenti dati numerici.
Operatori AND (&), OR (|) e XOR (^) bit per bit
Se uno degli operandi è associato tardivamente o se entrambi gli operandi sono valori letterali, entrambi verranno assegnati forzatamente al tipo int (System.Int32), quindi verrà eseguita l'operazione e il valore restituito sarà di tipo int.
Se entrambi gli operandi sono associati anticipatamente o se uno degli operandi è un valore letterale mentre l'altro è associato anticipatamente, verranno eseguiti ulteriori passaggi. Il tipo assegnato forzatamente a entrambi gli operandi dipende da due condizioni:
Se nessuno degli operandi è di tipo integrale, entrambi verranno assegnati forzatamente al tipo int.
Se uno solo degli operandi è di tipo integrale, l'altro verrà assegnato forzatamente al tipo integrale oppure al tipo int, qualunque sia il tipo più lungo.
Se uno degli operandi è più lungo, il tipo cui l'operando verrà assegnato forzatamente avrà la stessa lunghezza dell'operando più lungo.
Se uno degli operandi è di tipo unsigned, l'operando verrà assegnato forzatamente al tipo unsigned. In caso contrario, verrà assegnato forzatamente al tipo con segno.
Gli operandi verranno quindi assegnati forzatamente al tipo appropriato, verrà eseguita l'operazione bit per bit e restituito il relativo risultato. Il tipo di dati del risultato sarà lo stesso tipo degli operandi oggetto della coercizione.
Se si utilizza un valore letterale di valore integrale con un operatore bit per bit e una variabile associata anticipatamente, il valore letterale verrà interpretato come int, long, ulong o double a seconda di quale tra questi sia il tipo più piccolo in grado di rappresentare il numero. I valori decimal letterali vengono assegnati forzatamente al tipo double. Il tipo di dati del valore letterale può essere sottoposto a ulteriore coercizione in base alle regole appena descritte.
Operatore NOT bit per bit (~)
Se l'operando è associato tardivamente, oppure rappresenta un valore in virgola mobile o letterale, verrà assegnato forzatamente al tipo int (System.Int32), quindi verrà eseguita l'operazione NOT e il valore restituito sarà di tipo int.
Se l'operando è un tipo di dati integrale associato anticipatamente, verrà eseguita l'operazione NOT e restituito un tipo dello stesso tipo dell'operando.
Operatori di spostamento a sinistra bit per bit (<<) e di spostamento a destra bit per bit (>>)
Se l'operando di sinistra è associato tardivamente, oppure rappresenta un valore in virgola mobile o letterale, verrà assegnato forzatamente al tipo int (System.Int32). In caso contrario, l'operando di sinistra è un tipo di dati integrale associato anticipatamente e non verrà eseguita alcuna coercizione. L'operando di destra verrà sempre assegnato forzatamente al tipo di dati integrale. L'operazione di spostamento verrà quindi eseguita sui valori sottoposti a coercizione e il tipo del risultato restituito sarà lo stesso dell'operando di sinistra, se associato anticipatamente, oppure int.
Operatori di spostamento a destra senza segno (>>>)
Se l'operando di sinistra è associato tardivamente, oppure rappresenta un valore in virgola mobile o letterale, verrà assegnato forzatamente al tipo uint (System.Int32). In caso contrario, l'operando di sinistra è un tipo di dati integrale associato anticipatamente e verrà assegnato forzatamente a un tipo unsigned della stessa dimensione. Un tipo int, ad esempio, verrà assegnato forzatamente al tipo uint. L'operando di destra verrà sempre assegnato forzatamente al tipo di dati integrale. L'operazione di spostamento verrà quindi eseguita sui valori sottoposti a coercizione e il tipo del risultato restituito sarà lo stesso dell'operando di sinistra, se associato anticipatamente, oppure uint.
Il risultato dello spostamento a destra senza segno è sempre sufficientemente piccolo da poter essere memorizzato nella versione con segno del tipo restituito senza che si verifichi overflow.