คำถามติดแท็ก bit-manipulation

การจัดการของแต่ละบิต ตัวดำเนินการที่ใช้อาจประกอบด้วยค่าบิตและ AND, OR, XOR, NOT, กะซ้ายและขวากะ

16
แนวทางปฏิบัติที่ดีที่สุดสำหรับการดำเนินการกะวงกลม (หมุน) ใน C ++
ตัวดำเนินการกะซ้ายและขวา (<< และ >>) มีอยู่แล้วใน C ++ อย่างไรก็ตามฉันไม่พบว่าฉันสามารถดำเนินการกะแบบวงกลมหรือหมุนได้อย่างไร สามารถดำเนินการเช่น "หมุนซ้าย" และ "หมุนขวา" ได้อย่างไร? หมุนขวาสองครั้งที่นี่ Initial --> 1000 0011 0100 0010 ควรส่งผลให้: Final --> 1010 0000 1101 0000 ตัวอย่างจะเป็นประโยชน์ (หมายเหตุบรรณาธิการ: วิธีทั่วไปหลายอย่างในการแสดงการหมุนใน C ต้องทนทุกข์ทรมานจากพฤติกรรมที่ไม่ได้กำหนดหากจำนวนการหมุนเป็นศูนย์หรือรวบรวมมากกว่าคำสั่งเครื่องหมุนเพียงครั้งเดียวคำตอบของคำถามนี้ควรบันทึกแนวทางปฏิบัติที่ดีที่สุด)

17
วิธีที่ง่ายที่สุดในการทดสอบว่าตัวเลขเป็นเลขยกกำลัง 2 ใน C ++ อย่างไร
ฉันต้องการฟังก์ชั่นเช่นนี้: // return true iff 'n' is a power of 2, e.g. // is_power_of_2(16) => true is_power_of_2(3) => false bool is_power_of_2(int n); ใครช่วยแนะนำว่าฉันจะเขียนสิ่งนี้ได้อย่างไร คุณช่วยบอกฉันว่ามีเว็บไซต์ดีๆที่สามารถหาอัลกอริทึมประเภทนี้ได้ไหม

1
ลำดับความสำคัญและการดำเนินการ bitmask
ฉันเจอเคสที่แปลกมาก (ดูเหมือน) ใช้หมายเลข 2 ( 0b10) และ bitmask ด้วย 1 ( 0b01) สิ่งนี้ควรสร้าง0b00ซึ่งเทียบเท่ากับ 0 อย่างไรก็ตามนี่คือสิ่งที่ Mr Schrödingerเข้ามา: var_dump(0b10 & 0b01); // int(0) var_dump(0b10 & 0b01 == 0); // int(0) var_dump(0b10 & 0b01 != 0); // int(0) เหล้าวิสกี้. แทงโก้. ฟ็อกซ์ทรอต ฉันยอมรับว่าไม่ใช่คนที่คมที่สุดเมื่อพูดถึงตัวดำเนินการระดับบิต - ดังนั้นฉันอาจจะผิดพลาดอย่างน่ากลัวตรงไหน อย่างไรก็ตามใน Python: 0b10 & 0b01 == 0 = …

3
CHAR_BIT คืออะไร
การอ้างรหัสสำหรับการคำนวณค่าสัมบูรณ์จำนวนเต็ม (abs) โดยไม่แยกจากhttp://graphics.stanford.edu/~seander/bithacks.html : int v; // we want to find the absolute value of v unsigned int r; // the result goes here int const mask = v >> sizeof(int) * CHAR_BIT - 1; r = (v + mask) ^ mask; รูปแบบที่จดสิทธิบัตร: r = (v ^ mask) - mask; …

7
C / C ++: บังคับลำดับฟิลด์บิตและการจัดตำแหน่ง
ฉันอ่านว่าลำดับของเขตข้อมูลบิตภายในโครงสร้างเป็นแพลตฟอร์มเฉพาะ แล้วถ้าฉันใช้ตัวเลือกการบรรจุเฉพาะของคอมไพเลอร์ที่แตกต่างกันข้อมูลการรับประกันนี้จะถูกจัดเก็บตามลำดับที่ถูกต้องตามที่เขียนหรือไม่ ตัวอย่างเช่น: struct Message { unsigned int version : 3; unsigned int type : 1; unsigned int id : 5; unsigned int data : 6; } __attribute__ ((__packed__)); บนโปรเซสเซอร์ Intel ที่มีคอมไพเลอร์ GCC ฟิลด์ต่างๆจะถูกจัดวางไว้ในหน่วยความจำตามที่แสดง Message.versionเป็น 3 บิตแรกในบัฟเฟอร์และMessage.typeตามด้วย หากฉันพบตัวเลือกการบรรจุโครงสร้างที่เทียบเท่ากันสำหรับคอมไพเลอร์ต่างๆสิ่งนี้จะเป็นข้ามแพลตฟอร์มหรือไม่


10
มีวิธีที่สวยงามและรวดเร็วในการทดสอบให้ 1 บิตในจำนวนเต็มอยู่ในพื้นที่ที่ติดกันหรือไม่?
ฉันต้องการทดสอบว่าตำแหน่ง (จาก 0 ถึง 31 สำหรับจำนวนเต็ม 32 บิต) ที่มีค่าบิต 1 เป็นพื้นที่ที่ต่อเนื่องกันหรือไม่ ตัวอย่างเช่น: 00111111000000000000000000000000 is contiguous 00111111000000000000000011000000 is not contiguous ฉันต้องการให้การทดสอบนี้คือฟังก์ชันบางอย่างhas_contiguous_one_bits(int)เป็นแบบพกพา วิธีหนึ่งที่ชัดเจนคือการวนซ้ำตำแหน่งเพื่อค้นหาบิตเซ็ตแรกจากนั้นบิตแรกที่ไม่ได้ตั้งค่าและตรวจสอบบิตที่กำหนดเพิ่มเติม ฉันสงสัยว่ามีวิธีที่เร็วกว่านี้หรือไม่? หากมีวิธีการที่รวดเร็วในการค้นหาบิตชุดสูงสุดและต่ำสุด (แต่จากคำถามนี้ดูเหมือนว่าไม่มีแบบพกพา) การใช้งานที่เป็นไปได้คือ bool has_contiguous_one_bits(int val) { auto h = highest_set_bit(val); auto l = lowest_set_bit(val); return val == (((1 << (h-l+1))-1)<<l); } เพื่อความสนุกสนานนี่คือ 100 จำนวนเต็มแรกที่มีบิตต่อเนื่องกัน: 0 1 2 …


8
การลบจำนวนเต็ม 8 บิตในจำนวนเต็ม 64- บิตโดย 1 ในแบบขนาน, SWAR โดยไม่มีฮาร์ดแวร์ SIMD
ถ้าฉันมีจำนวนเต็ม 64- บิตที่ฉันตีความเป็นอาร์เรย์ของจำนวนเต็ม 8 บิตที่บรรจุด้วย 8 องค์ประกอบ ฉันต้องลบค่าคงที่1จากจำนวนเต็มที่บรรจุแต่ละตัวขณะจัดการล้นโดยไม่มีผลลัพธ์ขององค์ประกอบหนึ่งที่มีผลต่อผลลัพธ์ขององค์ประกอบอื่น ฉันมีรหัสนี้ในขณะนี้และใช้งานได้ แต่ฉันต้องการวิธีแก้ปัญหาที่การลบของแต่ละจำนวนเต็ม 8 บิตบรรจุในแบบคู่ขนานและไม่ทำให้การเข้าถึงหน่วยความจำ ใน x86 ฉันสามารถใช้คำสั่ง SIMD เช่นpsubbนั้นลบจำนวนเต็ม 8 บิตพร้อมกัน แต่แพลตฟอร์มที่ฉันกำลังเข้ารหัสไม่รองรับคำแนะนำ SIMD (RISC-V ในกรณีนี้) ดังนั้นฉันจึงพยายามที่จะทำSWAR (SIMD ภายในการลงทะเบียน)เพื่อยกเลิกการเผยแพร่ด้วยตนเองระหว่างไบต์ของ a uint64_tทำสิ่งที่เทียบเท่ากับสิ่งนี้: uint64_t sub(uint64_t arg) { uint8_t* packed = (uint8_t*) &arg; for (size_t i = 0; i < sizeof(uint64_t); ++i) { packed[i] -= 1; …
77 c++  c  bit-manipulation  simd  swar 

6
(x | y) - y ทำไมมันไม่เป็นแค่ x หรือแม้แต่ `x | 0`
ฉันกำลังอ่านรหัสเคอร์เนลและที่เดียวที่ฉันเห็นนิพจน์ภายในifคำสั่งเช่น if (value == (SPINLOCK_SHARED | 1) - 1) { ............ } โดยที่SPINLOCK_SHARED = 0x80000000เป็นค่าคงที่ที่กำหนดไว้ล่วงหน้า ฉันสงสัยว่าทำไมเราต้องใช้(SPINLOCK_SHARED | 1) - 1เพื่อการแปลงประเภท ผลลัพธ์ของนิพจน์จะเป็น 80000000 - เหมือนกับ 0x80000000 ใช่ไหม แต่ทำไม ORing 1 และ Subtracting 1 ถึงสำคัญ? มีความรู้สึกเหมือนว่าฉันพลาดที่จะรับบางสิ่งบางอย่าง ..

3
สำหรับจำนวนเต็มสองจำนวน A และ B ให้หาคู่ของตัวเลข X และ Y ที่ A = X * Y และ B = X xor Y
ฉันกำลังดิ้นรนกับปัญหานี้ฉันพบในหนังสือการเขียนโปรแกรมการแข่งขัน แต่ไม่มีวิธีแก้ปัญหาที่จะทำ สำหรับสองจำนวนเต็มAและB (สามารถใส่ในประเภทจำนวนเต็ม 64- บิต) โดยที่Aเป็นเลขคี่หาคู่ของตัวเลข X และ Y เพื่อให้A = X * Y และB = X x หรือ Y วิธีการของฉันคือรายการ ตัวหารทั้งหมดของ A และลองจับคู่ตัวเลขภายใต้ sqrt (A) กับตัวเลขเหนือ sqrt (A) ที่คูณถึงA และดูว่า xor ของพวกเขาเท่ากับBหรือไม่ แต่ฉันไม่รู้ว่ามันมีประสิทธิภาพเพียงพอหรือไม่ อะไรจะเป็นทางออกที่ดี / อัลกอริทึมสำหรับปัญหานี้

4
เหตุใด C คอมไพเลอร์จึงปรับสวิตช์ให้เหมาะสมและหากต่างกัน
ฉันกำลังทำงานในโครงการส่วนบุคคลเมื่อเร็ว ๆ นี้เมื่อฉันเจอปัญหาแปลก ๆ ในวงที่แน่นมากฉันมีจำนวนเต็มที่มีค่าระหว่าง 0 ถึง 15 ฉันต้องได้รับ -1 สำหรับค่า 0, 1, 8, และ 9 และ 1 สำหรับค่า 4, 5, 12, และ 13 ฉันหันไปใช้ godbolt เพื่อตรวจสอบตัวเลือกสองสามตัวและรู้สึกประหลาดใจที่ดูเหมือนว่าคอมไพเลอร์ไม่สามารถปรับคำสั่งสวิตช์ให้เหมาะสมเช่นเดียวกับโซ่ถ้า ลิงก์อยู่ที่นี่: https://godbolt.org/z/WYVBFl รหัสคือ: const int lookup[16] = {-1, -1, 0, 0, 1, 1, 0, 0, -1, -1, 0, 0, 1, 1, 0, 0}; …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.