Hiểu Nhanh Toán Tử Thao Tác Bit Trong Java - Techmaster

byte (8 bit)

  • short (16 bit)

  • int (32 bit)

  • long (64 bit)

  • và cả kiểu char (16 bit)

    Okay, lý thuyết vậy đủ rồi, tiếp tục với những thú vị khác của các toán tử thao tác bit nhé.

    1. Toán tử thao tác bit bổ sung đơn phân [~]

    Toán tử này tên quá rối, nhưng hiểu đơn giản là cách đảo chiều giá trị bit. Khi ta đặt ký hiệu ~ trước một biến giá trị, nó sẽ đảo chiều tất cả các giá trị bit của biến đó (đảo từ 0 sang 1 và ngược lại.). Khi chuyển về dạng số nguyên, giá trị số nguyên mới sẽ cộng thêm 1 và bị đảo từ âm sang dương hoạc ngược lại.Xem ví dụ sau để hiểu rõ hơn về toán tử này: public static void main(String[] args) { int x = 5; System.out.println("Value of x: "+x); System.out.println("Value of x in binary form: "+Integer.toBinaryString(x)); System.out.println("Value of ~x: "+~x); System.out.println("Value of ~x in binary form: "+ Integer.toBinaryString(~x)); } //Output //Value of x: 5 //Value of x in binary form: 11111111111111111111111111111010 //Value of ~x: -6 //Value of ~x in binary form: 000000000000000000000000000000101

    2. Toán tử thao tác bit AND [&]

    Khác với kiểu toán tử thao tác bit bổ sung đơn phân [~], kiểu toán tử thao tác bit AND [&] cần có 2 toán hạng (giá trị đầu vào) để thao tác.

    Về cách thức, toán tử thao tác bit AND [&] rất giống toán tử thao tác AND [&] với giá trị nguyên, khi so sánh 2 giá trị bit là 1 thì kết quả trả về là 1, trong khi các trường hợp khác thì trả về 0.

    Ví dụ: So sánh 0110 và 1100 thì kết quả trả về sẽ là 0100 vì chỉ có mỗi số thứ 2 giống nhau đều là 1.

    3. Toán tử thao tác bit OR [|]

    Toán tử thao tác bit OR [|] khi so sánh 2 giá trị bit chỉ cần chứa 1 giá trị là 1 thì sẽ trả về 1, nếu cả 2 giá trị bằng 0 thì sẽ trả về 0.

    Ví dụ: so sánh 01010 và 10100 thì kết quả sẽ trả về là 11110 vì từ số thứ 1 đến thứ 4 đều chứa 1, số thứ 5 cả 2 giá trị đều là 0.

    4. Toán tử thao tác bit đơn nhất XOR[^]

    Toán tử thao tác bit XOR trả về kết quả 1 chỉ với trường hợp duy nhất khi cả 2 giá trị bit so sánh đều là 1.

    Ví dụ: so sánh 0101 và 1011 thì kết quả sẽ trả về là 0001 vì chỉ có duy nhất số thứ 2 là có kết quả bit của cả 2 giá trị bằng 1.

    5. Bảng tóm tắt các toán tử thao tác bit

    Bảng tổng hợp dưới đây tóm tắt các toán tử thao tác bit đã học ở trên với giá trị so sánh là A và B.

    A

    B

    A & B

    A | B

    A ^ B

    1

    0

    0

    1

    1

    0

    1

    0

    1

    1

    1

    1

    1

    1

    0

    0

    0

    0

    0

    0

    III. Các toán tử đổi vị trí bit

    1. Toán tử Signed Left Shift [<<]

    Toán tử Signed Left Shift – gọi ngắn gọn là bit left shift cần 2 toán hạng để thực hiện, địa chỉ bit của toán hạng thứ nhất sẽ lùi về bên trái một số bằng với số của toán hạng thứ 2. Ví dụ:

    Giá trị bit của số 5 có dạng:

    00000000 00000000 00000000 00000101

    Ta thực hiện toán tử bit left shift, lùi về 3 số bên trái với giá trị bit của 5: 5 << 3

    Khi này giá trị bit của 5 sẽ trở thành:

    00000000 00000000 00000000 00101000

    Nếu in giá trị bit này ra, ta sẽ được giá trị số nguyên mới là 40. Quy tắc đơn giản để tính giá trị số nguyên mới sau khi thực hiện toán tử bit shift là: giá trị số nguyên mới = giá trị số nguyên cũ nhân với 2 bậc n, trong đó n là chính số lùi về bên trái. Vậy trong trường hợp này, địa chỉ mới sẽ có giá trị là 5 x 2^3 = 40.

    Địa chỉ bit ở trên có 32 số, với phép toán tử bit left shift, bạn có vài lưu ý hết sức thú vị sau:

    • Kiểu dữ liệu byte, short hay char đều chuyển về kiểu số int (32 bit) với phép toán tử này.

    • Giới hạn phép toán tử bit shift chỉ lùi về được 32 số, nếu ta thực hiện toán tử với một số >32, phép tính sẽ thực hiện với chỉ duy nhất số hàng đơn vị. Ví dụ 5 << 35 sẽ tương đương với 5 < 3.

    • Toán tử bit shift không có xử lý ngoại lệ (exception).

    2. Toán tử Right Shift [>>] và số âm dạng bit trong Java

    Toán tử Right Shift chia làm hai kiểu, kiểu nhận dấu (signed) và kiểu không nhận dấu (unsigned), điểm khác biệt giữa hai toán tử dạng bit right shift nằm ở kiểu bit của số âm.

    Và trước khi đi vào tìm hiểu kỹ về hai toán tử này, ta ôn qua một chút về kiểu bit số âm trong Java. Khi một số nguyên được biểu thị trên màn hình máy tính, ta có thể dễ dàng phân biệt qua dấu “-“ phía trước để biết đâu là số âm, đâu là số dương. Nhưng biểu diễn kiểu gì đễ phân biệt số âm và số dương kiểu bit?, vì kiểu bit chỉ có thể biểu đạt 2 giá trị duy nhất là 0 và 1.

    Trong Java, để biểu diễn một số âm dưới dạng bit được chuyển từ các bước sau:

    · 28 được viết dưới dạng bit là: 00011100

    · Đảo số từ 1 và 0 cho nhau ta được: 11100011

    · Thêm 1 vào số bit mới ta được số bit của giá trị -28 là: 11100100

    Cần chú ý là theo quy tắc "Most Significant", số bit hàng đầu tiên bên trái là 1 nếu là số âm, và là 0 nếu là số dương.

    3. Toán tử nhận dấu Signed Right Shift [>>]

    Tương tự với toán tử bit left shift, cách tính >> n sẽ là giá trị mới = giá trị cũ chia cho 2^n nếu n là số chẵn và = giá trị cũ cộng 1 và chia với 2^n nếu n là số lẻ.

    Điểm đặc biệt với toán tử bit signed right shift là giá trị cũ là giá trị âm thì sẽ luôn là âm, giá trị cũ là dương thì sẽ luôn là dương sau khi thao tác toán tử này. Xem ví dụ thao tác trên bit sau để hiểu rõ nguyên tắc toán tử này. // Using right shift operator with negative number in Java int number = -2; System.out.println(number); System.out.println("Before shift : " + Integer.toBinaryString(number)); number = number >> 1; System.out.println(number); System.out.println("After shift : " + Integer.toBinaryString(number)); //Output // -2 //Before shift : 11111111111111111111111111111110 // -1 //After shift : 11111111111111111111111111111111

    Như vậy, phép toán tử này luôn giữ giá trị đầu tiên bên trái, nên giá trị âm sẽ luôn âm và dương thì luôn dương.

    4. Toán tử không nhận dấu Unsigned Right Shift [>>]

    Với phép toán tử này, giá trị đầu tiên bên trái sẽ chuyển thành 0 do các giá trị sau bị lùi đi một số bằng n lần sang bên phải. Chính vì vậy cả giá trị âm lẫn dương đều chuyển thành số dương sau khi toán tử được thực hiện. Xem ví dụ sau để hiểu rõ hơn về toán tử này. public class RightShiftWithoutSignDemo{ public static void main(String args[]) { // Using unsigned right shift with negative number in Java // we can use binary literals from JDK 1.7 to assign // binary values to an integer, 0b is for binary, similar to 0x of hexadecimal int number = 0b1111_1000_1111_1010_1111_1000_1111_1010; System.out.println("Before unsigned right shift : " + Integer.toBinaryString(number)); System.out.println("number in decimal format : " + number); number = number >>> 1; //shift 1 bit using right shift without sign System.out.println("After unsigned right shift : " + Integer.toBinaryString(number)); System.out.println("number in decimal format : " + number); } } //Output //Before unsigned right shift : 11111000111110101111100011111010 //number in decimal format : -117769990 //After unsigned right shift : 01111100011111010111110001111101 //number in decimal format : 2088598653

    5. Toán tử gán kép với bit

    Tương tự với toán tử gán kép với số nguyên, ta cũng có kiểu toán tử gán kép với bit được thực hiện bằng cách rút gọn như sau.

    |=

    x |= 5

    x = x | 5

    ^=

    x ^= 5

    x = x ^ 5

    &=

    x &= 5

    x = x & 5

    <<=

    x <<= 5

    x = x << 5

    >>=

    x >>= 5

    x = x >> 5

    >>>=

    x >>>= 5

    x = x >>> 5

    |=

    x |= 5

    x = x | 5

    ^=

    x ^= 5

    x = x ^ 5

    IV. Kết luận

    Sử dụng toán tử thao tác bit cực kỳ hữu dụng trong trường hợp bạn muốn tăng tốc độ xử lý của phần cứng, cụ thể là trong lập trình nhúng C. Nhưng cái giá phải trả là những đoạn code khó đọc với những ai chưa quen các toán tử dạng này.

    Theo quan điểm của tác giả, toán tử thao tác bit là một khái niệm thú vị liên quan đến lập trình và khoa học máy tính mà bạn nên biết, nhưng bạn phải hạn chế sử dụng toán tử bit chừng nào có thể vì theo thời gian, phong cách lập trình hiện đại luôn đề cao tính tường minh và dễ hiểu của những đoạn code.

    Lập trình Java cơ bản và nâng cao

    Lập trình Web Java Spring 2018

    Bình luận

    boqfdbc51cocjsdqmp30avatarduongtieuchi 2020-02-01 03:55:46.133432 +0000 UTCPhần toán từ Xor sai rồi!!! Trả lời Avatar Bình luận Hủyboqga3c51cocjsdqmp3gavatarQuang Nh 2020-02-01 04:57:28.866591 +0000 UTCĐúng rồi xor trả về 1 khi 1 trong 2 phần tử so sánh = 1, còn lại trả về 0, edit sau, thanks bạn nhé Trả lời Avatar Bình luận Hủyc41sdtc51cofiu3hst80avataranh minh 2021-07-30 09:33:35.18262 +0000 UTC

    phần toán tử thao tác bit bổ sung đơn phân chỗ ví dụ output sai không nhỉ, mình chạy thử thì nó ra như này

    Value of x: 5Value of x in binary form: 101Value of ~x: -6Value of ~x in binary form: 11111111111111111111111111111010

    Trả lời Avatar Bình luận Hủy * Vui lòng đăng nhập trước khi bình luận.Ảnh đại diện 0 Thích Chia sẻ
  • Từ khóa » Toán Tử Dịch Phải Bit