ไม่กี่วันที่ผ่านมาสมาชิกของ StackExchange Anto ได้สอบถามเกี่ยวกับการใช้งานที่ถูกต้องสำหรับตัวดำเนินการบิตที่ชาญฉลาด ฉันระบุว่าการขยับเร็วกว่าการคูณและหารจำนวนเต็มด้วยพลังของสอง Daemin สมาชิก StackExchange โต้กลับโดยระบุว่าการเปลี่ยนทางขวานำเสนอปัญหาด้วยจำนวนลบ
ณ จุดนี้ฉันไม่เคยคิดที่จะใช้ตัวดำเนินการ shift กับจำนวนเต็มที่ลงนามแล้ว ฉันใช้เทคนิคนี้เป็นหลักในการพัฒนาซอฟต์แวร์ระดับต่ำ ดังนั้นฉันมักจะใช้จำนวนเต็มไม่ได้ลงนาม C ดำเนินการทางตรรกะกับจำนวนเต็มที่ไม่ได้ลงนาม ไม่มีการจ่ายความสนใจให้กับบิตลงชื่อเมื่อดำเนินการเลื่อนตรรกะอย่างถูกต้อง บิตที่ว่างจะถูกเติมด้วยค่าศูนย์ อย่างไรก็ตาม C ดำเนินการกะการคำนวณทางคณิตศาสตร์เมื่อเลื่อนจำนวนเต็มทางขวาที่ลงนาม บิตที่ว่างจะถูกเติมด้วยบิตเครื่องหมาย ความแตกต่างนี้ทำให้ค่าลบถูกปัดเศษเป็นอนันต์แทนที่จะถูกปัดเศษเป็นศูนย์ซึ่งเป็นพฤติกรรมที่แตกต่างจากการหารจำนวนเต็มที่ลงนามแล้ว
ความคิดเพียงไม่กี่นาทีส่งผลให้เกิดโซลูชั่นอันดับหนึ่ง วิธีการแก้ปัญหาแปลงค่าลบให้เป็นค่าบวกก่อนที่จะขยับ ค่าจะถูกแปลงแบบมีเงื่อนไขกลับสู่รูปแบบลบหลังจากดำเนินการกะแล้ว
int a = -5;
int n = 1;
int negative = q < 0;
a = negative ? -a : a;
a >>= n;
a = negative ? -a : a;
ปัญหาเกี่ยวกับการแก้ปัญหานี้คือคำสั่งการกำหนดเงื่อนไขมักจะแปลเป็นคำสั่งการกระโดดอย่างน้อยหนึ่งคำสั่งและคำสั่งการกระโดดอาจมีราคาแพงในโปรเซสเซอร์ที่ไม่ได้ถอดรหัสเส้นทางการเรียนการสอนทั้งสอง ต้องมีการปรับปรุงขั้นตอนการสอนซ้ำสองครั้งทำให้บุ๋มที่ดีในการเพิ่มประสิทธิภาพใด ๆ ที่ได้รับจากการเลื่อนมากกว่าการหาร
จากที่กล่าวมาข้างต้นฉันตื่นขึ้นมาในวันเสาร์พร้อมกับคำตอบของปัญหาการมอบหมายตามเงื่อนไข ปัญหาการปัดเศษที่เราพบเมื่อดำเนินการกะการคำนวณทางคณิตศาสตร์เกิดขึ้นเฉพาะเมื่อทำงานกับการแสดงส่วนประกอบสองอย่างเท่านั้น มันไม่ได้เกิดขึ้นกับการเป็นตัวแทนของคน วิธีการแก้ไขปัญหาเกี่ยวข้องกับการแปลงค่าส่วนเสริมของสองเป็นค่าส่วนเสริมก่อนที่จะดำเนินการเปลี่ยนแปลง จากนั้นเราต้องแปลงค่าส่วนเสริมกลับไปเป็นค่าส่วนประกอบสองตัว น่าแปลกที่เราสามารถดำเนินการชุดนี้ได้โดยไม่ต้องแปลงค่าลบอย่างมีเงื่อนไขก่อนดำเนินการกะ
int a = -5;
int n = 1;
register int sign = (a >> INT_SIZE_MINUS_1) & 1
a = (a - sign) >> n + sign;
ค่าลบเชิงบวกของสองถูกแปลงเป็นค่าลบส่วนเติมเต็มโดยลบหนึ่งค่า ในทางกลับกันค่าลบที่เป็นส่วนประกอบหนึ่งจะถูกแปลงเป็นค่าลบที่เป็นส่วนประกอบของสองโดยการเพิ่มหนึ่งค่า รหัสดังกล่าวข้างต้นงานเพราะบิตเครื่องหมายที่ใช้ในการแปลงจากส่วนประกอบที่สองที่จะเติมเต็มหนึ่งและในทางกลับกัน เฉพาะค่าลบจะมีการตั้งค่าบิตเครื่องหมายของพวกเขา; ดังนั้นเครื่องหมายตัวแปรจะเท่ากับศูนย์เมื่อaเป็นบวก
จากที่กล่าวมาข้างต้นคุณสามารถนึกถึงแฮ็กบิตที่ฉลาดคนอื่น ๆ อย่างที่กล่าวไว้ข้างต้นซึ่งได้ทำให้มันกลายเป็นกระเป๋าของคุณ? แฮ็คที่ชาญฉลาดที่คุณชื่นชอบคืออะไร? ฉันมักจะมองหาแฮ็กที่ชาญฉลาดบิตที่มุ่งเน้นประสิทธิภาพใหม่