Các toán tử =, +=, -=, *=, /=, %= là khá quen thuộc nên Tôi sẽ không giải thích các toán từ này:
1) Toán tử <<= (Left Shift, then assignment). Tôi gọi nôm na là đẩy bit qua bên trái
Ví dụ 1:
int x=5;
int y=2;
x=x<<y;
System.out.println(x);
Chúng ta sẽ có kết quả là 20
Quá trình nó thực hiện như sau:
– Phân tích số thập phân thành nhị phân
số x=5 sang nhị phân : 00000101
– Biểu thức x=x<<y, trước tiên vế phải được thực hiện trước, nó sẽ đẩy dãy nhị phân x=5 qua bên trái 2 bit ( vì y =2)
tức là: 00000101 sẽ thành 00010100 (sau khi đẩy qua trái thì các bit bên phải sẽ trở thành 0), số nhị phân 00010100 sẽ có giá trị là: 2^4+2^2=16+4=20 . Như vậy cuối cùng ta được x=20.
Ví dụ 2:
int x=11;
int y=4;
x=x<<y;
System.out.println(x);
Chúng ta sẽ có kết quả là 176
Quá trình nó thực hiện như sau:
– Phân tích số thập phân thành nhị phân
số x=11 sang nhị phân : 00001011
– Biểu thức x=x<<y, trước tiên vế phải được thực hiện trước, nó sẽ đẩy dãy nhị phân x=11 qua bên trái 4 bit ( vì y =4)
tức là: 00001011 sẽ thành 10110000(sau khi đẩy qua trái thì các bit bên phải sẽ trở thành 0), số nhị phân 10110000sẽ có giá trị là: 2^7+2^5+2^4=128+32+16=176 . Như vậy cuối cùng ta được x=176.
Tương tự đối với số âm, đầu tiên bạn cứ dịch chuyển bit y chang như số dương bên trên, sau đó thêm dấu âm (-) vào đằng trước kết quả. Tức là giả sử x=-11, y=4 thì x=x<<y sẽ có kết quả là -176.
2) Toán tử >>= (Right Shift with sign, then assignment). Tôi gọi nôm na là đẩy bit qua bên phải
Trường hợp này số dương và số âm nó có khác biệt lớn.
– Đối với số dương nó sẽ dịch chuyển các bit qua bên phải, các bit trái sẽ =0
Ví dụ 1: Giả sử ta có đoạn lệnh bên dưới:
int x=13;
int y=1;
x=x>>y;
System.out.println(x);
Kết quả ta được là 6
Trước tiên nó cũng phân tích 13 ra số nhị phân như sau: 00001101 sau đó biểu thức x=x>>y sẽ dịch chuyển x=13 qua bên phải 1 bit, tức là ta sẽ được 00000110, như vậy sẽ cho ra kết quả 2^2+2^1 =4+2=6
Ví dụ 2: Giả sử ta có đoạn lệnh bên dưới:
int x=45;
int y=2;
x=x>>y;
System.out.println(x);
Kết quả ta được là 11
Trước tiên nó cũng phân tích 45 ra số nhị phân như sau: 00101101 sau đó biểu thức x=x>>y sẽ dịch chuyển x=45 qua bên phải 2 bit, tức là ta sẽ được 00001011, như vậy sẽ cho ra kết quả 2^3+2^1+2^0 =8+2+1=11
– Đối với số âm (trước tiên các bạn phải xem qua Topic biểu diễn số âm trong máy tính http://duythanhcse.wordpress.com/2012/01/02/cach-bi%E1%BB%83u-di%E1%BB%85n-s%E1%BB%91-am-trong-may-tinh-ph%C6%B0%C6%A1ng-phap-bu-2/)
Giả sử các bạn đã thông thạo phương pháp bù 2 để biểu diễn số Âm trong máy tính, giờ Tôi sẽ viết đoạn lệnh trong Java để kiểm chứng kết quả cho toán tử >>:
int x=-45;
int y=2;
x=x>>y;
System.out.println(x);
Trước tiên bạn phải đổi -45 sang nhị phân = 1101 0011 . Nếu bạn chưa biết cách đổi thì bạn vào Topic biểu diễn số âm bằng phương pháp bù 2 (xem link bên trên).
Dòng lệnh x=x>>y, tức là dịch chuyển x qua phải 2 bit (vì y=2). Sau khi dịch chuyển ta sẽ được kết quả như sau: 1111 0100
Để biết được số nhị phân 1111 0100 có giá trị là bao nhiêu khi chuyển sang hệ thập phân, các bạn làm như sau:
– Tiến hành đảo bit 1111 0100 thành => 0000 1011
– Sau đó cộng thêm 1 vào kết quả 0000 1011, ta được 0000 1100
– Như vậy kết quả sẽ được : 2^3+2^2 = 8+4=12, với dấu đằng trước là Âm, nên kết quả ta được -12
Tức là khi dòng lệnh System.out.println(x); thực hiện thì ta sẽ được -12
3)>>>= (Right Shift with zero, then assignment) – Chú ý phép toán này dựa trên mẫu 32 bit.
Trường hợp này nếu là số Dương (>0) thì >>>= sẽ giống như >>= (Tức là kết quả của toán tử >>= cho kết quả như thế nào thì >>>= cũng cho kết quả như vậy). Do đó trong trường hợp số Dương bạn sẽ xem phần giải thích >>=
Bây giờ Tôi hướng dẫn trường hợp số âm (<0).
Ví dụ 1: – Bạn nhớ tự so sánh với cách làm của toán tử >>= xem chúng khác nhau ở bước nào nhé.
int x=-11;
int y=2;
x=x>>>y;
Trước tiên ta cũng biểu diễn -11 về dạng nhị phân như sau: 11111111 11111111 11111111 1111 0101
(Tôi giả sử các bạn đã biết phương pháp Bù 2)
lệnh x>>>y tức là dời x qua bên phải 2 bit : 00111111 11111111 11111111 1111 1101
Ở bước này ta được kết quả và gán cho biến x luôn (tức là nó khác với >>=, toán tử >>= sẽ đảo bit, sau đó +1 để tính ngược ra số thập phân). Còn đối với >>>= thì không cần, tại đây ta tính luôn:
00111111 11111111 11111111 1111 1101
=2^29+……..2^3+2^2+2^0= 1073741821
Ví dụ 2:
int x=-45;
int y=10;
x=x>>>y;
Biết rằng sau khi thực hiện thì x=4194303, bạn thử tự chạy bằng tay xem có đúng như vậy không nhé.
4) &= (Bitwise AND, then Assignment)
– Các bạn hiểu nôm na là các bit đều giống nhau là 1 thì sẽ cho kết quả 1, chỉ cần 1 bit là 0 thì sẽ cho kết quả là 0.
Ví dụ 1:
int x=5;
int y=6;
x=x&y;
Chuyển 5 thành nhị phân 0101
Chuyển 6 thành nhị phân 0110
Tiến hành Bitwise And
0101
&
0110
—————-
0100
System.out.println(x); ==> kết quả sẽ là 4 vì 0100 => 2^2=4
Ví dụ 2:
int x=–5;
int y=6;
x=x&y;
Chuyển – 5 thành nhị phân 1011 (dùng phương pháp bù 2)
Chuyển 6 thành nhị phân 0110
Tiến hành Bitwise And
1011
&
0110
—————-
0010
System.out.println(x); ==> kết quả sẽ là 4 vì 0010 => 2^1=2
5) |= (Bitwise OR, then Assignment)
– Chỉ cần 1 bit là 1 thì sẽ cho kết quả 1, cả 2 bit là 0 thì mới cho kết quả 0:
Ví dụ:
int x=13;
int y=3;
x=x|y;
Chuyển 13 sang nhị phân: 1101
Chuyển 3 sang nhị phân : 0011
Tiến hành Bitwise OR hai số nhị phân trên ta được:
1101
|
0011
————-
1111
System.out.println(x); Sẽ cho kết quả 15 vì 1111 đổi ra thập phân =2^3+2^2+2^1+2^0 =15
Tương tự cho số âm, bạn dùng phương pháp bù 2, sau đó dùng Bitwise OR giống như ví dụ trên.
6) ^= (Bitwise XOR, then Assignment)
– Các bit khác nhau sẽ cho giá trị 1, giống nhau sẽ cho giá trị 0.
Ví dụ:
int x=11;
int y=2;
x=x^y;
Chuyển 11 sang hệ nhị phân: 1011
Chuyển 2 sang hệ nhị phân : 0010
Tiến hành Bitwise XOR:
1011
^
0010
————–
1001
System.out.println(x); kết quả sẽ cho giá trị 9, bởi vì số nhị phân 1001 đổi qua thập phân = 2^3+2^0=9
Như vậy Tôi đã hướng dẫn khái quát các toán tử khó.
Các bạn phải cố gắng đọc hiểu để làm bài tập cho tốt!
Chúc các bạn thành công.