ตัวดำเนินการระดับบิต ในภาษา JavaScript
ในบทนี้ เป็นเนื้อหาของตัวดำเนินการระดับบิตในภาษา JavaScript คุณจะได้เรียนรู้ว่าตัวดำเนินการระดับบิตคืออะไร และมันถูกนำไปใช้อย่างไรในการเขียนโปรแกรม
ตัวดำเนินการระดับบิต
ตัวดำเนินการระดับบิต (Bitwise operators) คือตัวดำเนินการที่ดำเนินการในระบิตของข้อมูล โดยทั่วไปแล้วตัวดำเนินการระดับบิตมักใช้ในการเขียนโปรแกรมระดับต่ำ (Low level) เนื่องจากมันมีการทำงานที่เรียบง่ายและรวดเร็วในการคำนวณและเปรียบเทียบค่า เพราะการทำงานนั้นเกิดขึ้นกับแต่ละบิตในหน่วยความจำโดยตรง
ในบทนี้ เราจะใช้ตัวตัวดำเนินการระดับบิตกับตัวเลขจำนวนเต็มเพื่อความง่าย ในการเขียนคอมพิวเตอร์นั้น ข้อมูลจะถูกเก็บในหน่วยความจำในรูปแบบของเลขฐานสอง (Binary form) นี่เป็นตารางแสดงความสัมพันธ์ค่าของตัวเลขจาก 0 ถึง 15 กับค่าที่เก็บในหน่วยความจำ
DECIMAL BINARY DECIMAL BINARY
0 0000 8 1000
1 0001 9 1001
2 0010 10 1010
3 0011 11 1011
4 0100 12 1100
5 0101 13 1101
6 0110 14 1110
7 0111 15 1111
ในตัวอย่าง เป็นการแสดงค่าในรูปแบบเลขฐานสองของตัวเลข 0 ถึง 15 ในทางทฤษฎีแล้ว ภาษา JavaScript นั้นเก็บตัวเลขโดยใช้หน่วยความจำ 64 บิต นั่นหมายความว่า 5 ถูกเก็บในหน่วยความจำเป็น ...0101
โดยที่ ...
หน้าตัวเลขนั้นประกอบไปด้วย 0
อีก 60 ตัว ในกรณีนี้เราแสดงเพียงบิตทางด้านขวาสุดเพื่อความเรียบง่าย
ต่อไปมาดูกันว่าตัวดำเนินการระดับบิตนั้นมีอะไรบ้าง และนี่เป็นตารางของตัวดำเนินการระดับบิตทั้งหมดในภาษา JavaScript
สัญลักษณ์ | ตัวดำเนินการ | ตัวอย่าง |
---|---|---|
& | BIT AND | a & b |
| | BIT OR | a | b |
^ | BIT XOR | a ^ b |
~ | BIT INVERT | ~a |
<< | BIT SHIFT LEFT | a << n |
>> | BIT SHIFT RIGHT | a >> n |
ตัวดำเนินการระบิตนั้นทำงานคล้ายกับตัวดำเนินการตรรกศาสตร์ AND OR และ NOT แต่แทนที่จะจัดการกับค่า true
และ false
มันจะเป็นการทำงานกับแต่ละบิต 1
และ 0
ของข้อมูลแทน และนี่เป็นการทำงานของตัวดำเนินการแต่ละประเภท
- BIT AND: ได้ผลลัพธ์เป็น
1
ถ้าค่าบิตทั้งสองเป็น1
ไม่เช่นนั้นได้ผลลัพธ์เป็น0
- BIT OR: ได้ผลลัพธ์เป็น
1
ถ้าค่าบิตอย่างน้อยหนึ่งบิตเป็น1
ไม่เช่นนั้นได้ผลลัพธ์เป็น0
- BIT XOR: ได้ผลลัพธ์เป็น
1
ถ้าค่าบิตทั้งสองแตกต่างกัน ไม่เช่นนั้นได้ผลลัพธ์เป็น0
- BIT INVERT: กลับบิตจาก
1
เป็น0
และกลับบิตจาก0
เป็น1
- BIT SHIFT LEFT: เลื่อนบิตไปทางซ้าย
n
ตำแหน่ง และเติมบิต0
เข้ามาทางขวาเป็นจำนวนn
บิต - BIT SHIFT RIGHT: เลื่อนบิตไปทางขวา
n
ตำแหน่ง บิตทางขวาสุดn
ตำแหน่งจะถูกนำออกไป และเติมบิต0
เข้ามาทางซ้าย
หลังจากที่ได้รู้ว่าตัวดำเนินแต่ละแบบนั้นทำงานอย่างไร ต่อไปมาดูตัวอย่างการใช้งาน เรามาเริ่มกับตัวดำเนินการ BIT AND และ BIT OR กันก่อน
console.log(3 & 10); // 2
console.log(3 | 10); // 11
ในตัวอย่าง เป็นการใช้งานตัวดำเนินการระดับบิตเพื่อจัดการกับค่าบิตของตัวเลขจำนวนเต็ม เนื่องจากในหน่วยความจำ (ที่แสดงในตารางก่อนหน้า) ค่าของ 3
และ 10
ถูกเก็บในรูปแบบของเลขฐานสองเป็น 0011
และ 1010
ตามลำดับ ดังนั้น การทำงานของตัวดำเนินการ BIT AND และ BIT OR สามารถแสดงให้เห็นเป็นรูปภาพได้ดังนี้
BIT AND
0011 (3)
1010 (10)
====
0010 (2)
ตัวดำเนินการจะทำงานทีละคู่ของบิตโดยเริ่มจากบิตทางด้านขวาสุดของ 3
และ 10
ไปยังบิตที่อยู่ทางด้านซ้าย
ในการทำงานของ BIT AND จะเห็นว่าทั้งบิตของ 3
และ 10
ในตำแหน่งที่สองจากทางด้านซ้ายมีค่าเป็น 1
ทั้งคู่ ดังนั้นบิตผลลัพธ์จึงมีค่าเป็น 1
และบิตในตำแหน่งอื่นๆ มีค่าผลลัพธ์เป็น 0
ดังนั้นผลลัพธ์ที่ได้จากการดำเนินการคือ 0010
ซึ่งมีค่าเท่ากับ 2
ในฐานสิบ
BIT OR
0011 (3)
1010 (10)
====
1011 (11)
ในการทำงานของ BIT OR ถ้าหากค่าบิตอย่างน้อยหนึ่งบิตเป็น 1
บิตผลลัพธ์จะมีค่าเป็น 1
นั่นทำให้มีเพียงบิตตำแหน่งที่สองจากทางซ้ายเท่านั้นที่ได้บิตผลลัพธ์เป็น 0
ส่วนตำแหน่งอื่นจะได้บิตผลลัพธ์เป็น 1
ดังนั้นผลลัพธ์ที่ได้จากการดำเนินการคือ 1011
ซึ่งมีค่าเท่ากับ 11
ในฐานสิบ
ตัวดำเนินการ BIT NOT นั้นทำงานกับค่าเพียงหนึ่งค่าเท่านั้น นี่เป็นตัวอย่าง
console.log(~7); // -8
เมื่อเราใช้งานตัวดำเนินการ BIT NOT มันได้ทำการกลับค่าบิตของเครื่องหมายด้วย ซึ่งตัวเลขในภาษา JavaScript นั้นมีบิตสำหรับเก็บว่าตัวเลขเป็นจำนวนบวกหรือลบ โดย 0
หมายถึงค่าบวก และ 1
หมายถึงค่าลบ
SIGN DIGIT
0 0111
============
1 1000
ดังนั้นตัวดำเนินการ BIT NOT ทำงานในสองส่วนคือกลับบิตที่เก็บค่าของตัวเลขจาก 0111
เป็น 1000
และกลับบิตเครื่องหมายจาก 0
เป็น 1
ดังนั้นผลลัพธ์ที่ได้จึงเท่ากับ -8
นั่นเอง
ตัวอย่างถัดมาเป็นการใช้ตัวดำเนินการ BIT SHIFT LEFT และ BIT SHIFT RIGHT สำหรับเลื่อนบิตไปทางซ้ายและทางขวาตามลำดับ นี่เป็นตัวอย่าง
console.log(8 >> 2); // 2
console.log(5 << 2); // 20
ในตัวอย่าง เราได้เลื่อนบิตไปทางซ้ายสองตำแหน่ง และเลื่อนไปทางขวาสองตำแหน่ง ซึ่งสามารถแสดงการทำงานแบบรูปภาพได้ดังนี้
BIT SHIFT RIGHT
1000
>>>> by 2
0010
ในการเลื่อนบิต 1000
ไปทางขวาสองตำแหน่ง จะทำให้บิตทางด้านขวาสุดสองบิตถูกนำออกไป และบิต 0
สองบิตเลื่อนเข้ามาแทนจากทางซ้าย ทำให้ได้บิตผลลัพธ์เป็น 0010
ซึ่งมีค่าเท่ากับ 2
ในฐานสิบ
BIT SHIFT LEFT
0101
<<<< by 2
10100
สำหรับการเลื่อนบิต 0101
ไปทางซ้ายสองตำแหน่ง จะทำให้มีบิต 0
เพิ่มเข้ามาจากทางด้านขวาสองตำแหน่ง นั้นทำให้ได้บิตผลลัพธ์เป็น 10100
ซึ่งมีค่าเท่ากับ 20
ในฐานสิบ
สังเกตว่าในการเลื่อนบิตไปทางขวาหนึ่งตำแหน่งจะทำให้ค่าลดลงครึ่งหนึ่ง และการเลื่อนบิตไปทางซ้ายหนึ่งตำแหน่งจะทำให้ค่าเพิ่มขึ้นสองเท่า
การแสดงตัวเลขในรูปแบบเลขฐานสอง
เมื่อคุณต้องการทำงานกับตัวเลขในรูปแบบเลขฐานสอง ยกตัวอย่างเช่น ต้องการทราบว่าตัวเลขแสดงในรูปแบบของฐานสองเป็นอย่างไร คุณสามารถให้เมธอด toString
เพื่อแปลงตัวเลขให้เป็น String ในเลขฐานสองได้ โดยกำหนดพารามิเตอร์ที่สองเป็น 2
นี่เป็นตัวอย่าง
console.log((3).toString(2)); // 11
console.log((10).toString(2)); // 1010
console.log((0.5).toString(2)); // 0.5
console.log((2.8).toString(2)); // 10.110011...
และในทางกลับกัน ถ้าหากคุณมี String ของตัวเลขในรูปแบบเลขฐานสองและต้องการแปลงเป็นตัวเลขจำนวนเต็ม คุณสามารถใช้ฟังก์ชัน parseInt
โดยใส่พารามิเตอร์ตัวที่สองเป็น 2
เพื่อแปลงจากเลขฐานสองเป็นจำนวนเต็มได้ นี่เป็นตัวอย่าง
let a = parseInt("11", 2);
let b = parseInt("1010", 2);
console.log(a); // 3
console.log(b); // 10
และนี่เป็นผลลัพธ์การทำงานของตัวอย่างการใช้ตัวดำเนินการระดับบิตของเรา โดยปกติแล้ว ฟังก์ชัน console.log
จะแสดงข้อมูลเป็นเลขฐานสิบเสมอ และเพื่อดูมันในรูปแบบของเลขฐานสอง เราใช้เมธอด toString
ในการแปลงก่อนการแสดงผล
console.log((3 & 10).toString(2)); // 10
console.log((3 | 10).toString(2)); // 1011
console.log((~7).toString(2)); // -1000
console.log((8 >> 2).toString(2)); // 10
console.log((5 << 2).toString(2)); // 10100
และนี่เป็นเพียงเทคนิคการใช้งานเมธอดเมื่อเราต้องทำงานกับตัวเลขและต้องการใช้มันในรูปแบบของเลขฐานสองเท่านั้น ในความเป็นจริงแล้วเมธอด toString
และ parseInt
สามารถทำงานกับตัวเลขฐานอื่นๆ ได้ เช่น ฐานแปด หรือฐานสิบหก เป็นต้น นี่เป็นรูปแบบการใช้งานของฟังก์ชันทั้งสอง
// Convert number to base n string
Number.toString(n);
// Parse string from base n to number (base 10)
Number.parseInt(str, n);
ในบทนี้ คุณได้เรียนรู้เกี่ยวกับตัวดำเนินการระดับบิตในภาษา JavaScript ซึ่งเป็นตัวดำเนินการที่เราสามารถใช้มันจัดการกับบิตของข้อมูลได้โดยตรง นอกจากนี้ เรายังแนะนำเทคนิคการใช้งานเมธอด toString
และ parseInt
สำหรับแปลงตัวเลขไปและกลับระหว่างฐาน 10 และเลขฐานอื่นๆ