การแนะนำ
ถ้าคนนับในระบบเลขฐานสิบ คอมพิวเตอร์ก็จะนับในระบบไบนารี่ และโปรแกรมเมอร์จะต้องเข้าใจวิธีการพูดคุยกับทั้งคนและคอมพิวเตอร์ การทบทวนนี้น่าจะช่วยได้ในเรื่องนี้ บางครั้งก็มีโลกทั้งใบที่ซ่อนอยู่เบื้องหลังสิ่งที่ชัดเจน ฉันเสนอที่จะพูดคุยเกี่ยวกับโลกนี้ เช่น หนึ่งสัปดาห์มี 7 วัน ตอนนี้เรามาตอบคำถาม: ตัวเลข “7” คืออะไร? ) ประการแรก มันคือจำนวนธรรมชาติจำนวนเต็ม (บวก) เป็นเลขทศนิยมด้วย
เลขทศนิยมคือตัวเลขในระบบทศนิยม เมื่อเราพูดว่า "ระบบเลขฐานสิบ" หมายความว่าระบบตัวเลข
มีฐาน 10 ฐานแสดงจำนวนหลักที่สามารถใช้ในระบบตัวเลขที่กำหนดเพื่อแสดงตัวเลขได้ การนับถอยหลังคือจากศูนย์ ดังนั้น เพื่อแสดงตัวเลขในระบบเลขฐานสิบ เราจึงใช้ตัวเลขตั้งแต่ 0 ถึง 9 ซึ่งเป็นสิ่งที่ดี แต่เราต้องนับไม่เพียงแค่ 9 เท่านั้น แต่ยังต้องนับเกินด้วย จะเป็นอย่างไร? เช่น เลข 10 ในการเขียนเลขนี้ให้ใช้ตัวเลขมากถึง 2 หลัก ตำแหน่งของแต่ละหลักในระบบทศนิยมเรียกว่าตำแหน่งทศนิยม ตัวเลขนับจากขวาไปซ้าย:
นอกจากนี้ เลขทศนิยมยังสามารถขยายได้ดังนี้ 103 = 1*10^2 + 0*10^1 + 3*10^0
โดยพื้นฐานแล้วจำนวนจะเพิ่มขึ้นจากขวาไปซ้าย นั่นคือตอนแรกเป็น 7 แล้วกลายเป็น 10 ดังนั้นให้นับเลขจากด้านขวาเริ่มจากศูนย์ ทั้งหมดนี้เพื่ออะไร? นี่เป็นเพราะเราไม่ใช่คอมพิวเตอร์ และในขณะที่เรานับเป็นทศนิยม (นั่นคือ ฐาน 10) คอมพิวเตอร์จะนับเป็นฐานสอง (นั่นคือ ฐาน 2) แต่กฎที่ใช้กับระบบตัวเลขเหล่านี้ก็เหมือนกัน
ระบบไบนารี่
ระบบไบนารี่คล้ายกับระบบทศนิยมมาก โดยข้อแตกต่างเพียงอย่างเดียวคือขีดจำกัดที่นี่ไม่ใช่ 10 แต่เป็น 2 ลองเปรียบเทียบกับตัวอย่างกัน เราจะแทน 11 ในรูปแบบไบนารี่ได้อย่างไร? ง่ายมาก: คุณเพียงแค่ต้องหารเลขทศนิยมด้วยฐาน 2 นั่นคือนับ 11/2 ในคอลัมน์ ตัวอย่าง:
หรือนี่คือตัวอย่างจาก WikiHow:
สิ่งที่น่าสนใจคือ เราสามารถแสดงตัวเลขในรูปแบบไบนารี่ได้เช่นเดียวกับในรูปแบบทศนิยม: 111 ในไบนารี่ = 1*2^2 + 1*2^1 + 1*2^0 = 4 + 2 + 1
คุณสามารถดูตัวอย่างการแปลงจากไบนารี่เป็นทศนิยมได้ในเครื่อง
คิดเลขออนไลน์ เมื่อพูดถึงความจริงที่ว่ากฎการดำเนินการในระบบตัวเลขเหมือนกัน ลองดูที่การเพิ่มในระบบไบนารี่:
อย่างที่คุณเห็น เราถ่ายโอนตัวเลขระหว่างการบวกในลักษณะเดียวกับในระบบทศนิยม สามารถดูการวิเคราะห์การบวกได้ที่นี่:
อย่างไรก็ตาม มีการกล่าวถึงคำว่า "ปลดประจำการ" เป็นระยะๆ และมันคืออะไร?
สถานที่เป็นเพียง "องค์ประกอบโครงสร้าง" ของการแทนตัวเลข นั่นคือหมายเลข 10 ประกอบด้วยตัวเลขสองหลัก: เราต้องการ 2 หลัก 2 ตำแหน่ง 2 องค์ประกอบในการเขียนหมายเลขนี้ เป็นสิ่งสำคัญสำหรับเราที่จะเข้าใจสิ่งนี้เพราะ
ในระบบเลขฐานสอง ตัวเลขเป็นบิต . คำว่า Bit มาจากภาษาอังกฤษ
"เลขฐานสอง"ซึ่งก็คือเลขฐานสอง อาจเป็น 0 หรือ 1 ก็ได้ แต่ในขณะที่เราอ่านตัวเลขและคำโดยรวม ไม่ใช่ตัวอักษรต่อตัวอักษร คอมพิวเตอร์ก็ไม่ได้อ่านทีละบิต สำหรับ
"ชิ้นส่วน" ขั้นต่ำของข้อมูลที่ประมวลผลใน RAM (ที่เรียกว่าหน่วยข้อมูลที่เล็กที่สุดที่สามารถระบุตำแหน่งได้)
ลำดับของ 8 บิตจะถูกอ่าน เนื่องจากมี 8 อัน จึงเรียกว่า "ออคเต็ต" และ - คำที่รู้จักกันดีมากขึ้น
Byte . เพื่อจำออคเต็ต คุณสามารถจำได้ว่าคำว่าปลาหมึกยักษ์ (แปดขา) แปลเป็นภาษาอังกฤษว่าปลาหมึกยักษ์ นั่นคือนี่คือ "octo" เดียวกันทุกประการในชื่อ:
ลองคิดดูว่าจำนวนสูงสุดที่เราสามารถแทนได้เป็น 8 บิตคือเท่าใด?
และคำถามก็เกิดขึ้น: แล้วจำนวนลบล่ะ? เพื่อทำความเข้าใจสิ่งนี้ เรามาพูดถึงวิธีการแสดงไบต์ใน Java กัน
ชวาและไบต์
เราสามารถใช้ตัวเลขติดลบใน Java ได้อย่างไร? มันทำได้ง่ายๆ ใน Java ไบต์จะถูกเซ็นชื่อ หลัก/บิตซ้ายสุด (เรียกอีกอย่างว่า "บิตที่สำคัญที่สุด") ถูกสร้างขึ้นเป็น "เครื่องหมาย" ที่ตอบคำถาม: "ตัวเลขนี้เป็นลบหรือไม่" หากคำตอบคือใช่ แสดงว่าเครื่องหมายมีค่าเป็น 1 มิฉะนั้นจะเป็น 0 ลองดูตัวอย่างวิธีเปลี่ยนเลข 5 ให้เป็นลบ 5:
จากภาพนี้ คุณสามารถเข้าใจขีดจำกัดของค่าไบต์ได้:
เป็นที่ชัดเจนว่า:
- ถ้าเราบวกหนึ่งเข้ากับ 127 เราจะได้ -128
- ถ้าเราลบหนึ่งจาก -128 เราจะได้ 127
ดังนั้น Byte ใน Java สามารถรับค่าได้ตั้งแต่ -128 ถึง 127 อย่างที่เราจำได้ ไบต์คือออคเต็ต และหลักสูงสุด/บิตที่มีนัยสำคัญที่สุดจะมีหมายเลขซีเรียลเป็น 7 เนื่องจากเรานับจากศูนย์ ในกรณีนี้ ให้จำง่ายๆ ว่าไบต์มีค่าเท่ากับ -2 ยกกำลัง 7 (ขีดจำกัดล่าง) ถึง 2 ยกกำลัง 7 ลบ 1 (ขีดจำกัดบน) การทำงานกับชนิดข้อมูลนั้นเป็นเรื่องง่าย เราใช้คอมไพเลอร์ Java ออนไลน์ “repl.it” เป็น “แซนด์บ็อกซ์” สำหรับบทความนี้ https://repl.it/languages/java. ตัวอย่างเช่น ลองรันโค้ดที่จะแสดงตัวแปรไบต์ในรูปแบบไบนารี่เป็นสตริง:
class Main {
public static void main(String[] args) {
byte octet = 5;
String bin = String.format("%8s", Integer.toBinaryString(octet)).replace(' ', '0');
System.out.println(bin);
}
}
การทำงานกับไบต์จะถูกใช้งานเมื่อทำงานกับ I/O Streams คุณสามารถอ่านเพิ่มเติมได้ในบทช่วยสอนจาก Oracle: "
I/O Streams " นอกจากนี้ ใน Java คุณสามารถใช้ลิเทอรัลพิเศษเพื่อระบุค่าเป็นบิตได้:
class Main {
public static void main(String[] args) {
byte data = 0b101;
System.out.println(data);
}
}
การจัดการบิต
เมื่อสัมผัสกับไบต์และบิต เราไม่สามารถพลาดที่จะพูดถึงการปรับแต่งบิตต่างๆ การดำเนินการที่พบบ่อยที่สุดคือกะ (กะระดับบิตหรือกะบิต) และทั้งหมดเป็นเพราะผลลัพธ์ของพวกเขามีประโยชน์ในทางปฏิบัติที่ชัดเจน มีประโยชน์อะไร? การเลื่อนไปทางซ้ายด้วยตำแหน่ง N เทียบเท่ากับการคูณตัวเลขด้วย 2N และการเลื่อนไปทางขวาจะคล้ายกับการหารเดียวกัน ดังนั้น 5<<2 == 5*Math.pow(2,2) และเพื่อทำความเข้าใจว่าเหตุใดจึงเป็นเช่นนั้น
การปฏิเสธระดับบิต NOT (Unary bitwise) ซึ่งแสดงด้วยเครื่องหมายตัวหนอน จะกลับบิต เขียนเป็นเครื่องหมายตัวหนอน เช่น ~5
public static void main(String[] args) {
System.out.println(~5);
System.out.println(~-5);
}
นี่แสดงให้เห็นอีกครั้งว่าเมื่อ Java เปลี่ยนเครื่องหมายของตัวเลข นอกเหนือจากการกลับค่าบิตที่ส่วนท้ายสุดแล้ว เรายังดำเนินการ +1 อีกด้วย และหากไม่มีสิ่งนี้ อย่างที่เราเห็น หมายเลข 5 ของเราก็เปลี่ยนไป และเพื่อให้ยังคงเป็นเลขเดิมก่อนเปลี่ยนเครื่องหมาย คุณต้อง +1 ก่อน Bitwise AND ให้คุณปล่อยตัวเลขสองตัวที่แตกต่างกันที่มีค่า 1 ไว้เพียงเล็กน้อยเท่านั้นหากบิตทั้งหมดมีค่าเป็นหนึ่ง สิ่งที่น่าสนใจเกี่ยวกับเรื่องนี้อาจเป็นเพราะมีประโยชน์ในการใช้งานบางประการ:
int x=4;
System.out.println((x&1) != 1);
รหัสนี้จะตรวจสอบหมายเลข x เพื่อความเท่าเทียมกัน ลองดูตัวอย่าง:
เมื่อใช้ Bitwise AND และ Bitwise OR ร่วมกัน คุณจะสามารถใช้มาสก์ได้:
public static void main(String[] args) {
byte optionA=0b0100;
byte optionB=0b0010;
byte optionC=0b0001;
byte value = (byte)(optionB | optionC);
if ((optionC & value) != 0b0000) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
ดู " ตัวเลือกการปิดบังด้วยตัวดำเนินการระดับบิตใน Java " สำหรับราย ละเอียด เพิ่มเติม การจัดการบิตเป็นหัวข้อที่น่าสนใจซึ่งมีการเขียนบทวิจารณ์ บทความ และหนังสือแยกกัน และจากที่นี่เส้นทางอันยาวไกลสู่การเข้ารหัสจะเริ่มต้นขึ้น ส่วนหนึ่งของการทบทวนนี้ ควรทำความเข้าใจว่าเหตุใดจึงทำงานและอย่างไร สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการดำเนินการบิต ฉันแนะนำให้อ่านบทวิจารณ์จาก tproger: “
เกี่ยวกับการดำเนินการบิต ”
ประเภทดั้งเดิม
ดังนั้น ไบต์ก็คือออคเต็ต ซึ่งก็คือ 8 บิต เป็นเรื่องง่ายที่จะจำไว้ว่าใน Java ยังมี 8 ประเภทดั้งเดิมโดยบังเอิญ ประเภทดั้งเดิมคือประเภทข้อมูลที่สร้างขึ้นในภาษาการเขียนโปรแกรม ซึ่งพร้อมใช้งานตามค่าเริ่มต้น ไบต์เป็นชนิดข้อมูลดั้งเดิมที่เล็กที่สุดในแง่ของขนาดหน่วยความจำที่ Java สามารถใช้งานได้ ดังที่เราได้กล่าวไปแล้ว ไบต์หนึ่งใช้พื้นที่ถึง 8 บิต ดังนั้นตัวเลขที่สำคัญที่สุดคือหมายเลข 7 ดังนั้นไบต์จึงมีค่าตั้งแต่ -2 ถึงกำลังที่ 7 ถึง 2 ถึงกำลังที่ 7 ลบ 1 ของผลลัพธ์ มีประเภทดั้งเดิมอื่น ๆ อีกบ้าง:
ดังที่เราเห็นจากตาราง ประเภทข้อมูลในแง่ของจำนวนข้อมูลนั้นมีสองเท่า นั่นคือ short = 2 * ไบต์ และ int = 2 * short จริงๆแล้วมันเป็นเรื่องง่ายที่จะจำ จำไว้ว่าไบต์ = 8 บิต ความจริงที่ว่ามันไม่น้อยก็จำได้เช่นกัน จำนวนเต็มในภาษาอังกฤษเรียกว่าจำนวนเต็ม ประเภทดั้งเดิมจากนั้นเรียกว่าตัวย่อ int มีจำนวนเต็มปกติ - int มีทั้งแบบสั้น แบบสั้น และแบบยาว แบบยาว ดังนั้น int จึงมีขนาด 32 บิต (4 ไบต์) เวอร์ชันสั้นมีขนาดเล็กกว่า 2 เท่า - 16 บิต (2 ไบต์) และเวอร์ชันยาวจะมีขนาดใหญ่เป็นสองเท่านั่นคือ 64 บิต (8 ไบต์) ดังนั้น int จึงสามารถจัดเก็บจำนวนได้ประมาณ 2 พันล้านและหนึ่งร้อยล้าน และระยะยาวสามารถเก็บได้สูงสุดประมาณ 9 พันล้าน (คำดี) เมื่อนึกถึงเรื่องตลกเก่า ๆ เกี่ยวกับวิธีที่โปรแกรมเมอร์มือใหม่คิดว่า 1,000 ไบต์ใน 1 กิโลไบต์ และโปรแกรมเมอร์ที่สมบูรณ์เชื่อว่าใน 1 กิโลกรัมมี 1,024 กรัม เราสามารถเข้าใจได้:
1 mb = 1024 Kbyte = 1024 * 1024 = 1048576 bytes
1 int = 4 bytes
1 mb = 262144 int
อย่างไรก็ตาม ผู้อ่านที่สนใจอาจสังเกตเห็นว่าในภาพมีเพียง 7 ประเภทเท่านั้น 8 ประเภทดั้งเดิมคือบูลีน boolean เป็นประเภทข้อมูลแบบบูลีนที่มีค่าเพียงสองค่า: จริงและเท็จ แต่คำถามก็เกิดขึ้น - มันขนาดไหน? ข้อมูลจำเพาะ Java Virtual Machine และส่วน "
2.3.4. ประเภทบูลีน " จะตอบเรา:
นั่นคือ แค่บูลีนก็จะได้ปริมาณเท่ากับ int หากเราประกาศอาร์เรย์เป็นบูลีน แต่ละองค์ประกอบของอาร์เรย์จะมีขนาด 1 ไบต์ สิ่งเหล่านี้คือปาฏิหาริย์ :)
บทสรุป
ฉันขอแนะนำให้คุณทำความคุ้นเคยกับเอกสารอีกสองสามอย่างเพื่อรวบรวม:
#เวียเชสลาฟ
GO TO FULL VERSION