JavaRush /จาวาบล็อก /Random-TH /การปฏิเสธระดับ Bitwise - ทำไมจึงเป็นเช่นนั้น?
Alex Bolgov
ระดับ
Ташкент

การปฏิเสธระดับ Bitwise - ทำไมจึงเป็นเช่นนั้น?

เผยแพร่ในกลุ่ม
สวัสดีทุกคน :) ในขณะที่อ่านบทความการดำเนินการของ Bitwiseฉันก็เหมือนกับคนอื่นๆ ที่มีคำถาม: ทำไมเมื่อเรากลับเลข 342 เราได้ -343 นี่คือลักษณะที่ปรากฏในบทความ: การปฏิเสธระดับ Bitwise - ทำไมจึงเป็นเช่นนั้น - 1ผู้ที่มีความอยากรู้อยากเห็นเป็นพิเศษ (เช่นฉัน) มีคำถาม: "เฮ้ แต่ 010101001 น้อยกว่า 101010110 เป็นเหตุผลที่ควรน้อยกว่า 342 และเป็นบวก" โดยการพิมพ์ลงในตัวแปลงตัวเลขออนไลน์หรือตรวจสอบโดยใช้โค้ด:
Integer a = Integer.valueOf("010101001", 2);
System.out.println(Integer.toString(a, 10));
โดยไม่คาดคิดเราได้รับสิ่งอื่นที่ไม่ใช่ -343...
169
โอ้ ช่างดีเสียนี่กระไรที่กาลครั้งหนึ่งในชั้นเรียนการเขียนโปรแกรมภาษา C ฉันได้ยินอะไรบางอย่างเกี่ยวกับเลขเครื่องหมายเป็นจำนวนเต็ม หลังจากกูเกิ้ลไปสักพักก็อธิบายได้แล้วว่านี่คือสัตว์ชนิดไหน การปฏิเสธระดับ Bitwise - ทำไมจึงเป็นเช่นนั้น - 2จริงๆแล้วมีความไม่ถูกต้องในบทความซึ่งทำให้สับสน หากเราตรวจสอบด้วยโค้ดว่าจริงๆ แล้วผลลัพธ์ของการกลับเลข 342 คืออะไร:
int a = 342;
System.out.println(Integer.toBinaryString(~a));
แล้วเราจะเห็นผลที่แตกต่างออกไปเล็กน้อย
11111111111111111111111010101001
ทำไมจึงเป็นเช่นนี้? ประเด็นก็คือตัวแปรไม่สามารถมี 101010110 เพียงอย่างเดียวได้ จริงๆ แล้ว มันถูกเก็บไว้เป็น
000000000000000000000000101010110
ท้ายที่สุดแล้ว ตัวแปร int ใช้เวลา 4 ไบต์ เช่น 32 บิต - 32 เซลล์หน่วยความจำ หลังจากการผกผัน ตัวเลขทั้งหมดจะเปลี่ยนไปโดยสิ้นเชิง เช่น และ "ตัด" เลขศูนย์นำหน้า ตอนนี้ส่วนที่สนุกมา เนื่องจากในการแทนค่าไบนารี่ เครื่องหมาย + หรือ - หน้าตัวเลขไม่สามารถจัดเก็บได้ จึงมีเคล็ดลับอย่างหนึ่ง: บิตที่ 1 เองนั้นเป็นผู้รับผิดชอบต่อเครื่องหมายจริงๆ และเป็นบิตเครื่องหมายอย่างแม่นยำ และตัวเลขทั้งหมดจะถูกจัดเก็บตามตรรกะนี้: ตัวเลขตั้งแต่ 00...000 ถึง 01...111 เป็นบวก เริ่มต้นจาก 0 (เช่น ตั้งแต่ 0 ถึง 2147483647) และเริ่มต้นจาก 10...000 ถึง 11... 111 เป็นค่าลบ โดยเริ่มจากค่าที่น้อยที่สุดและลงท้ายด้วย -1 (เช่น -2147483648 ถึง -1)
00000000000000000000000000000000 = 0
01111111111111111111111111111111 = 2147483647
10000000000000000000000000000000 = -2147483648
11111111111111111111111111111111 = -1
แล้วคุณถามว่า"เอาล่ะ Navalny เราจะเชื่อคุณ แต่ทำไมคุณถึงตัดสินใจว่านี่คือวังของเขา"แต่ทำไมกลายเป็น -343 ทั้งหมดนี้ได้อย่างไร? มันง่ายมาก เราสามารถคำนวณสิ่งนี้ได้ด้วยตนเอง หากเรา "ตัด" (หรือแทนที่ด้วย 0) บิตแรกสุด จากเวอร์ชันไบนารี่ของผลลัพธ์หมายเลข 342 ( 1111111111111111111111111111111111111111010101001 ) และส่งคืนกลับเป็นรูปแบบทศนิยม
String s = "01111111111111111111111010101001";
System.out.println(s + " = " + Integer.toString(Integer.valueOf(s, 2), 10));
แล้วเราก็เข้าใจแล้ว
01111111111111111111111010101001 = 2147483305
อันที่จริง เราไม่ได้แค่ "ตัด" 1 ออกตั้งแต่ต้น แต่ยังลบ 1000000000000000000000000000000000 จากจำนวนนี้ ทีนี้ลองบวกกลับเข้าไปในรูปแบบทศนิยม สิ่งที่เราจะได้เห็น:
~342 =
11111111111111111111111010101001 =
//в двоичном виде//
01111111111111111111111010101001 +
10000000000000000000000000000000
=
//в десятичном виде//
-2147483648 + 2147483305 = -343
นี่คือหมายเลขที่ต้องการ -343 :) เพื่อนๆ นี่เป็นโพสต์แรกของฉันที่นี่ โปรดชอบมันหากคุณชอบและเป็นข้อมูล (ฉันต้องการรวบรวมความสำเร็จทั้งหมด จริงๆ 😄) คุณสามารถอ่านเพิ่มเติมเกี่ยวกับหัวข้อนี้ได้ที่นี่: ขอให้ทุกคนโชคดีและขอขอบคุณสำหรับความสนใจของคุณ)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION