Βιταμικές Υπολογιστές ECMAScript

位运算符是在数字底层(即表示数字的 32 个数位)进行操作的。

重温整数

ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数)。在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢?

有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数。数值范围从 -2147483648 到 2147483647。

可以以两种不同的方式存储二进制形式的有符号整数,一种用于存储正数,一种用于存储负数。正数是以真二进制形式存储的,前 31 位中的每一位都表示 2 的幂,从第 1 位(位 0)开始,表示 20,第 2 位(位 1)表示 21。没用到的位用 0 填充,即忽略不计。例如,下图展示的是数 18 的表示法。

Διπλής δεκαδικό αριθμός εκφρασμένος με 32 δυαδικούς αριθμούς

18 的二进制版本只用了前 5 位,它们是这个数字的有效位。把数字转换成二进制字符串,就能看到有效位:

var iNum = 18;
alert(iNum.toString(2));	//输出 "10010"

Αυτός ο κώδικας εκτυπώνει μόνο το "10010",而不是 18 的 32 位的表示。其他的数位并不重要,因为仅使用前 5 位即可确定这个十进制数值。如下图所示:

Διπλής δεκαδικός αριθμός εκφρασμένος με 5 δυαδικούς αριθμούς 18

Οι αρνητικοί αριθμοί αποθηκεύονται επίσης ως δυαδικός κώδικας, αλλά με τη μορφή της δυαδικής επιπλέον τιμής. Οι βήματα για τον υπολογισμό της δυαδικής επιπλέον τιμής ενός αριθμού είναι τρία: }}

  1. Καθορίστε τη δυαδική εκδοχή του μη αρνητικού αριθμού (π.χ., για να υπολογίσετε τη δυαδική επιπλέον τιμή του -18, πρέπει πρώτα να καθορίσετε τη δυαδική εκδοχή του 18)
  2. Υπολογίστε το δυαδικό αντιθέτο, δηλαδή αντικαταστήστε το 0 με το 1 και το 1 με το 0
  3. Προσθέστε 1 στο δυαδικό αντιθέτο

Για να καθορίσετε τη δυαδική εκδοχή του -18, πρώτα πρέπει να λάβετε την δυαδική εκδοχή του 18, όπως παρακάτω:

0000 0000 0000 0000 0000 0000 0001 0010

Επόμενο, υπολογίστε το δυαδικό αντιθέτο, όπως παρακάτω:

1111 1111 1111 1111 1111 1111 1110 1101

Τελευταία, προσθέστε 1 στο δυαδικό αντιθέτο, όπως παρακάτω:

1111 1111 1111 1111 1111 1111 1110 1101
                                      1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110

Επομένως, η δυαδική εκδοχή του -18 είναι 1111 1111 1111 1111 1111 1111 1110 1110. θυμήσου ότι κατά τη χειρισμό των υποzeichνιζόμενων ακέραιων, οι προγραμματιστές δεν μπορούν να προσβούν στη θέση 31.

Είναι ενδιαφέρον ότι όταν μετατρέπεται ο αρνητικός ακέραιος σε δυαδική αλφαριθμητική σειρά, το ECMAScript δεν το δείχνει με τη μορφή δυαδικής επιπλέον τιμής, αλλά με τη μορφή του δεδομένου αριθμού του αριθμού με το πρόσημο μισής τιμής. Για παράδειγμα:

var iNum = -18;
alert(iNum.toString(2));	//εκτυπώνει "-10010"

Το κώδικας αυτό εκτυπώνει "-10010", όχι τη δυαδική επιπλέον τιμή, για να αποφύγει την πρόσβαση στη θέση 31. Για απλότητα, το ECMAScript χειρίζεται τους ακέραιους με έναν απλό τρόπο, ώστε οι προγραμματιστές να μην ανησυχούν για τη χρήση τους.

Από την άλλη πλευρά, ο μη υποzeichνιζόμενος ακέραιος θεωρεί την τελευταία θέση ως μια άλλη θέση αριθμού. Σε αυτό το μοτίβο, η 32η θέση δεν δείχνει το σύμβολο του αριθμού, αλλά την τιμή 231Εξαιτίας αυτού του επιπλέοντος ψηφίου, το εύρος των τιμών του μη υποzeichνιζόμενου ακέραιου είναι από 0 έως 4294967295. Για ακέραιους που είναι μικρότεροι από 2147483647, ο μη υποzeichνιζόμενος ακέραιος φαίνεται όπως ο υποzeichνιζόμενος ακέραιος, ενώ για αυτούς που είναι μεγαλύτεροι από 2147483647, χρησιμοποιείται η θέση 31 (στην υποzeichνιζόμενη εκδοχή, αυτή η θέση είναι πάντα 0).

Με τη μετατροπή του μη υποzeichνιζόμενου ακέραιου σε αλφαριθμητικό, επιστρέφονται μόνο τα ισχυρά ψηφία του.

Σημείωση:Όλες οι ακέραιες απεικονίσεις αποθηκεύονται ως υποzeichνιζόμενοι ακέραιοι από default. Μόνο οι υπολογιστικές τροποποιητές του ECMAScript μπορούν να δημιουργήσουν μη υποzeichνιζόμενους ακέραιους.

Η υπολογιστική τροποποίηση NOT

Η υπολογιστική τροποποίηση NOT δείχνεται με το σημείο μηδέν (~) και είναι ένας από τους λίγους επαφές που σχετίζονται με τη δυαδική αριθμητική στο ECMAScript.

Η αριθμητική πράξη NOT είναι ένα τριπλό επεξεργαστικό πρόγραμμα:

  1. Μετατροπή του αριθμητικού στοιχείου σε 32-bit αριθμό
  2. Μετατροπή του δυαδικού αριθμού στο αντίθετο δυαδικό του
  3. Μετατροπή του δυαδικού αριθμού σε δεκαδικό αριθμό

Για παράδειγμα:

var iNum1 = 25;		//25 ισούται με 00000000000000000000000000011001
var iNum2 = ~iNum1;	//Μετατροπή σε 11111111111111111111111111100110
alert(iNum2);		//έξοδος "-26"

Η αριθμητική πράξη NOT είναι η διαδικασία της απόσπασης αρνητικού, μετά τη μείωση 1, οπότε 25 γίνεται -26. Μπορείτε επίσης να το αποκτήσετε με τον παρακάτω τρόπο:

var iNum1 = 25;
var iNum2 = -iNum1 -1;
alert(iNum2);	//έξοδος -26

Αριθμητική πράξη AND

Η αριθμητική πράξη AND σημειώνεται με το σύμβολο (&) και επεξεργάζεται άμεσα τη δυαδική μορφή των αριθμών. Στην ενότητα κάθε θέσης, ο αριθμητικός πράκτορας AND χρησιμοποιεί τους παρακάτω κανόνες:

Ψηφία του πρώτου αριθμού Ψηφία του δεύτερου αριθμού Αποτέλεσμα
1 1 1
1 0 0
0 1 0
0 0 0

Για παράδειγμα, για να διεξάγουμε την αριθμητική πράξη AND για τους αριθμούς 25 και 3, ο κώδικας είναι ως εξής:

var iResult = 25 & 3;
alert(iResult);	//έξοδος "1"

25 και 3 διεξάγουν την αριθμητική πράξη AND με αποτέλεσμα 1. Γιατί; Ανάλυση όπως ακολουθεί:

 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
AND = 0000 0000 0000 0000 0000 0000 0000 0001

Κάποια στιγμή, μόνο μια αριθμητική θέση (θέση 0) από τους 25 και 3 αποθηκεύεται το 1, οπότε οι άλλες θέσεις παράγουν το 0, οπότε το αποτέλεσμα είναι 1.

Αριθμητική πράξη OR

Η αριθμητική πράξη OR σημειώνεται με το σύμβολο (|) και επεξεργάζεται άμεσα τη δυαδική μορφή των αριθμών. Στην υπολογισμό κάθε θέσης, ο αριθμητικός πράκτορας OR χρησιμοποιεί τις παρακάτω κανόνες:

Ψηφία του πρώτου αριθμού Ψηφία του δεύτερου αριθμού Αποτέλεσμα
1 1 1
1 0 1
0 1 1
0 0 0

Επιμένουμε στη χρήση του αριθμητικού συμβολού AND, να διεξάγουμε την αριθμητική πράξη OR για 25 και 3, ο κώδικας είναι ως εξής:

var iResult = 25 | 3;
alert(iResult);	//έξοδος "27"

25 και 3 διεξάγουν την αριθμητική πράξη OR με αποτέλεσμα 27:

25 = 0000 0000 0000 0000 0000 0000 0001 1001
 3 = 0000 0000 0000 0000 0000 0000 0000 0011
--------------------------------------------
OR = 0000 0000 0000 0000 0000 0000 0001 1011

可以看出, σ'ν δύο αριθμούς, υπάρχουν 4 αριθμητικές θέσεις που αποθηκεύονται το 1, αυτές οι θέσεις μεταφέρονται στο αποτέλεσμα. Ο δυαδικός κώδικας 11011 ισούται με 27.

Συναρμολογητική πράξη XOR

Η συναρμολογητική πράξη XOR εκφράζεται με το σύμβολο (^), φυσικά, εκτελείται άμεσα στο δυαδικό μορφή. Η XOR είναι διαφορετική από την OR, επιστρέφει 1 μόνο όταν ένα ψηφίο από τους αριθμούς αποθηκεύεται με 1. Η αληθεια της τάβλας είναι ως εξής:

Ψηφία του πρώτου αριθμού Ψηφία του δεύτερου αριθμού Αποτέλεσμα
1 1 0
1 0 1
0 1 1
0 0 0

Για την εκτέλεση της συναρμολογητικής πράξης XOR μεταξύ των αριθμών 25 και 3, ο κώδικας είναι ως εξής:

var iResult = 25 ^ 3;
alert(iResult); // Εμφάνιση "26"

Το αποτέλεσμα της συναρμολογητικής πράξης XOR μεταξύ των αριθμών 25 και 3 είναι 26:

 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
XOR = 0000 0000 0000 0000 0000 0000 0001 1010

Από τα δύο αριθμήματα, υπάρχουν 4 ψηφία που αποθηκεύονται με 1, τα οποία μεταφέρονται στο αποτέλεσμα. Το δυαδικό κώδικας 11010 ισούται με 26.

Αριστερή κίνηση

Η αριστερή κίνηση εκφράζεται με δύο μικρότερες από κεινοί (<<). Με αυτόν τον τρόπο, όλα τα ψηφία του αριθμού μετακινούνται προς τα αριστερά για το καθορισμένο αριθμό θέσεων. Για παράδειγμα, όταν ο αριθμός 2 (ισούται με το δυαδικό 10) μετακινηθεί 5 θέσεις προς τα αριστερά, το αποτέλεσμα είναι 64 (ισούται με το δυαδικό 1000000):

var iOld = 2; // ισούται με το δυαδικό 10
var iNew = iOld << 5; // ισούται με το δυαδικό 1000000 δεκαδικό 64

Σημείωση:Στην αριστερή κίνηση των ψηφίων, το αριστερό μέρος του αριθμού έχει 5 κενά θέσεις. Η αριστερή κίνηση συμπληρώνει αυτές τις θέσεις με 0, ώστε το αποτέλεσμα να είναι ένας πλήρης 32-ψηφιακός αριθμός.

Αριθμός 2 με αριστερή μετατόπιση

Σημείωση:Η αριστερή κίνηση διατηρεί τη σημαία του αριθμού. Για παράδειγμα, αν ο αριθμός -2 μετακινηθεί 5 θέσεις προς τα αριστερά, θα��ιστεί -64, όχι 64. «Η σημαία εξακολουθεί να αποθηκεύεται στη 32η θέση;» Ναι, αλλά αυτό γίνεται στο ECMAScript υποβάθρο, και οι προγραμματιστές δεν μπορούν να έχουν πρόσβαση στη 32η θέση.Ακόμα και όταν ο αριθμός είναι αρνητικός και εμφανίζεται σε μορφή δεκαδικών αριθμών, εμφανίζεται η υπογραφή του αρνητικού (π.χ., -2 θα εμφανιστεί ως -10).

Συναρμολογητής αριστερού κινήματος προς τα δεξιά

Ο συναρμολογητής αριστερού κινήματος προς τα δεξιά εκφράζεται με δύο μεγαλύτερες από κεινοί (>>). Με αυτόν τον τρόπο, όλα τα ψηφία του 32-ψηφιακού αριθμού μετακινούνται προς τα δεξιά ολόκληρα, διατηρώντας την υπογραφή του αριθμού ( θετικό ή αρνητικό). Ο συναρμολογητής αριστερού κινήματος προς τα δεξιά είναι ακριβώς αντίθετος στο αριστερό κίνηση. Για παράδειγμα, όταν ο αριθμός 64 μετακινηθεί 5 θέσεις προς τα δεξιά, θα γίνει 2:

var iOld = 64;		// ισούται με το δυαδικό 1000000
var iNew = iOld >> 5;	// ισούται με το δυαδικό 10 δεκαδικό 2

Επίσης, η μετακίνηση θέσεων δημιουργεί κενές θέσεις. Αυτή τη φορά, οι κενές θέσεις βρίσκονται στα αριστερά του αριθμού αλλά μετά το σημείο του συμβόλου. Το ECMAScript συμπληρώνει αυτές τις κενές θέσεις με την τιμή του συμβόλου, δημιουργώντας ολοκληρωμένο αριθμό, όπως στο παρακάτω σχήμα:

Αριθμός 64 με σημείωση αριστεράς μετατόπιση

Μη υπογεγραμμένη δεξιά στρογγυλοποίηση

Ο μη υπογεγραμμένος δεξιός στρογγυλοποίηση εκφράζεται με τρία γράμματα μεγαλύτερα από το τριγωνικό (>>>), το οποίο μετακινεί ολόκληρη την υπογραμμένη 32-ψήφια αριθμητική ακολουθία προς τα δεξιά. Για τους θετικούς αριθμούς, το αποτέλεσμα της μη υπογεγραμμένης στρογγυλοποίησης είναι το ίδιο με τη συμβολομετρική στρογγυλοποίηση.

Με τον παράδειγμα της συμβολομετρικής στρογγυλοποίησης, αν ο 64 μετακινηθεί 5 θέσεις προς τα δεξιά, θα γίνει 2:

var iOld = 64;		// ισούται με το δυαδικό 1000000
var iNew = iOld >>> 5;	// ισούται με το δυαδικό 10 δεκαδικό 2

Για τους αρνητικούς αριθμούς, η κατάσταση είναι διαφορετική.

Η μη υπογεγραμμένη δεξιά στρογγυλοποίηση συμπληρώνει όλες τις κενές θέσεις με 0. Για τους θετικούς αριθμούς, αυτό είναι το ίδιο με τη συμβολομετρική στρογγυλοποίηση, ενώ οι αρνητικοί αριθμοί χειρίζονται ως θετικοί.

Επειδή το αποτέλεσμα της μη υπογεγραμμένης δεξιάς στρογγυλοποίησης είναι ένας 32-ψήφιος θετικός αριθμός, η μη υπογεγραμμένη δεξιά στρογγυλοποίηση των αρνητικών αριθμών οδηγεί πάντα σε έναν πολύ μεγάλο αριθμό. Για παράδειγμα, αν ο -64 μετακινηθεί 5 θέσεις προς τα δεξιά, θα αποκτήσει 134217726. Πώς θα αποκτήσουμε αυτό το αποτέλεσμα;

Για να επιτευχθεί αυτό, πρέπει να μετατρέψουμε τον αριθμό σε μια ανώνυμη ισοδύναμη μορφή (ακόμα και αν ο αριθμός αυτός είναι συμβολομετρικός), η οποία μπορεί να αποκτηθεί με τον παρακάτω κώδικα:

var iUnsigned64 = -64 >>> 0;

Στη συνέχεια, χρησιμοποιώντας το toString() του τύπου Number για να αποκτήσουμε την πραγματική παρουσίαση των θέσεων, η βάση είναι 2:

alert(iUnsigned64.toString(2));

Αυτό θα δημιουργήσει 11111111111111111111111111000000, δηλαδή την αριθμητική αντιστοιχία του συμβολομετρικού αριθμού -64, αλλά ισούται με τον μη συμβολομετρικό αριθμό 4294967232.

Για αυτόν τον λόγο, η χρήση του μη υπογεγραμμένου δεξιού στρογγυλοποίησης πρέπει να είναι προσεκτική.