C (gcc)ผู้ไม่เชื่อเรื่องพระเจ้า endian, ไม่มี libs มาตรฐาน, 92 91 ไบต์
h(n)เป็นฟังก์ชันเลขจำนวนเต็มฐานสิบหกหลักเดียว
f(x,p)ใช้จำนวนเต็มและchar[8]ตัวชี้ ผลลัพธ์คือ 8 ไบต์ของcharข้อมูล ( ไม่สิ้นสุด 0 ยกเว้นว่าผู้โทรทำเช่นนั้น)
สมมติฐาน: ชุดอักขระ ASCII ส่วนประกอบที่สมบูรณ์ของ 2 intดังนั้นการเปลี่ยนที่ถูกต้องในที่สุดจะทำให้บิตเครื่องหมายลงและการแปลง a uint32_tเพื่อintไม่ทำให้เกิดรูปแบบบิตหากตั้งค่าบิตสูงไว้ intอย่างน้อย 32- บิต (กว้างกว่าอาจปล่อยให้มันทำงานบนการใช้งานส่วนเสริมหรือเครื่องหมาย C ขนาด 1)
Non-สมมติฐาน: อะไรเกี่ยวกับการดำเนินการสั่งไบต์หรือ signedness charของ
i;h(n){n&=15;return n>9?n+87:n+48;}f(x,p)char*p;{for(i=5;--i;x>>=8)*p++=h(x>>4),*p++=h(x);}
ลองออนไลน์! รวมถึงผู้โทรทดสอบที่ใช้printf("%.8s\n", buf)พิมพ์บัฟเฟอร์เอาต์พุตโดยไม่ต้องจบการทำงาน 0
Ungolfed:
int h(n){n&=15;return n>9 ? n+'a'-10 : n+'0';} // single digit integer -> hex
int i;
void ungolfed_f(x,p)char*p;{
for(i=5; --i; x>>=8) // LS byte first across bytes
*p++=h(x>>4), // MS nibble first within bytes
*p++=h(x);
}
การทำn&=15;ข้างในh(x)เป็นแบบคุ้มทุน 6 ไบต์เทียบกับ 3 แต่ละอัน&15เพื่อแยกตอดต่ำที่ไซต์การโทรทั้งสอง
,เป็นจุดลำดับ (หรือเทียบเท่าในคำศัพท์ที่ทันสมัย) ดังนั้นจึงปลอดภัยที่จะทำ*p++= stuffสองครั้งในหนึ่งคำสั่งเมื่อคั่นด้วย,โอเปอเรเตอร์
>>ในจำนวนเต็มที่ลงนามจะถูกกำหนดให้ดำเนินการเป็นเลขคณิตหรือตรรกะ GNU C นิยามว่าเป็นส่วนประกอบของเลขคณิต 2 แต่ในเครื่องเสริมของ 2 มันไม่สำคัญเพราะเราไม่เคยดู 0 หรือสำเนาบิตของ shift-in ในที่สุด MSB ดั้งเดิมจะลงไปสู่ไบต์ต่ำที่ไม่เปลี่ยนแปลง นี่ไม่ใช่กรณีของเครื่องหมาย / ขนาดและฉันไม่แน่ใจเกี่ยวกับส่วนประกอบ 1 ของ
ดังนั้นนี่อาจเป็นแบบพกพาสำหรับการใช้งาน C เท่านั้น (หรือที่intเป็นที่กว้างขึ้นกว่า 32 บิตดังนั้นบิต 31 เป็นเพียงส่วนหนึ่งของขนาด.) ได้ลงนาม -> ลงนามแปลงยัง munges บิตรูปแบบสำหรับจำนวนเต็มลบดังนั้น&15บนintเท่านั้นที่จะดึงแทะของมูลค่าไม่ได้ลงนามเดิมในวันที่ 2 ของการเติมเต็ม อีกครั้งเว้นแต่intเป็นวงกว้างกว่า 32 บิตดังนั้นปัจจัยการผลิตทั้งหมดจะไม่เป็นลบ
รุ่น golfed มี UB จากการล้มปิดท้ายฟังก์ชั่นที่ไม่เป็นโมฆะ ที่จะไม่คืนค่าเพียงเพื่อหลีกเลี่ยงประกาศแทนการเริ่มต้นvoid intคอมไพเลอร์สมัยใหม่จะหยุดสิ่งนี้เมื่อเปิดใช้การเพิ่มประสิทธิภาพ
แรงจูงใจ: ฉันกำลังพิจารณาคำตอบ asm x86 หรือ ARM Thumb คิดว่ามันอาจสนุกที่จะทำมันด้วยตัวเองใน C บางทีสำหรับ asm ที่สร้างโดยคอมไพเลอร์เป็นจุดเริ่มต้น ดู/programming/53823756/how-to-convert-a-number-to-hexสำหรับ x86 asm ที่มีประสิทธิภาพด้านความเร็วรวมถึงรุ่น AVX512VBMI ที่มีเพียง 2 คำสั่ง (แต่ต้องการควบคุมเวกเตอร์สำหรับ vpmultishiftqb และ vpshufb ดังนั้นจะไม่ดีสำหรับการเล่นกอล์ฟ) โดยปกติจะใช้งานพิเศษสำหรับ SIMD เพื่อ byte-reverse ลงในคำสั่งการพิมพ์ใน x86 แบบ endian ดังนั้นการส่งออก hex แบบกลับด้านแบบไบต์จึงทำได้ง่ายกว่าปกติ
ความคิดอื่น ๆ
ฉันถือว่าการใช้จำนวนเต็มโดยการอ้างอิงและวนลูปผ่านไบต์ด้วยchar*ในการใช้งาน C-endian เล็ก ๆ น้อย ๆ (เช่น x86 หรือ ARM) แต่ฉันไม่คิดว่าจะช่วยได้มากนัก
ใช้sprintfในการทำครั้งละ 1 ไบต์, 64 ไบต์หลังจากเล่นกอล์ฟ:
int i;
void f(x,p)char*p;{
for(i=4;sprintf(p,"%.2x",x&255),--i;x>>=8)
p+=2;
}
แต่ถ้าเราใช้ printf เหมือนฟังก์ชั่นที่เราอาจรวมทั้งไบต์-swap และทำ%xprintf ของสิ่งที่ทั้งเหมือน@ คำตอบของ