C / C ++, 306 295 ไบต์
#define C(c)((c)>>1^((c)&1?0xEDB88320L:0))
#define K(c)(C(C(C(C(C(C(C(C(c))))))))),
#define F(h,l)K((h)|(l+0))K((h)|(l+1))K((h)|(l+2))K((h)|(l+3))
#define R(h)F(h<<4,0)F(h<<4,4)F(h<<4,8)F(h<<4,12)
unsigned long crc_table[]={R(0)R(1)R(2)R(3)R(4)R(5)R(6)R(7)R(8)R(9)R(10)R(11)R(12)R(13)R(14)R(15)};
ทำงานในสิ่งที่ตรงกันข้ามเราจบลงด้วยอาร์เรย์ยาวที่ไม่ได้ลงชื่อชื่อ crc_table เราสามารถตัดขนาดของอาร์เรย์ได้เนื่องจากแมโครจะตรวจสอบให้แน่ใจว่ามีองค์ประกอบทั้งหมด 256 รายการในอาร์เรย์ เราเริ่มต้นอาร์เรย์ด้วย 16 'แถว' ของข้อมูลโดยใช้ 16 invocations ของแมโคร R
การเรียกใช้ R แต่ละครั้งจะขยายออกเป็นสี่แฟรกเมนต์ (แมโคร F) ของค่าคงที่สี่ (แมโคร K) สำหรับข้อมูลทั้งหมด 16 คอลัมน์
มาโคร K เป็นลูปที่ไม่ได้ควบคุมซึ่งจัดทำดัชนีโดย k ในรหัสจากคำถามต้นฉบับ มันอัพเดตค่า c แปดครั้งโดยเรียกใช้แมโคร C
โซลูชันพื้นฐานของตัวประมวลผลล่วงหน้านี้ใช้หน่วยความจำสักเล็กน้อยระหว่างการขยายแมโคร ฉันพยายามทำให้สั้นลงเล็กน้อยด้วยการเพิ่มระดับการขยายตัวของแมโครและคอมไพเลอร์ของฉันก็ปุก รหัสข้างต้นคอมไพล์ (ช้า) กับทั้ง Visual C ++ 2012 และ g ++ 4.5.3 ภายใต้ Cygwin (RAM RAM Windows 7 64 บิต 8GB)
แก้ไข:
แฟรกเมนต์ด้านบนคือ 295 ไบต์รวมถึง white space หลังจากขยายมาโครทั้งหมดยกเว้น C จะเพิ่มเป็น 9,918 ไบต์ เมื่อขยายมาโคร C แต่ละระดับขนาดจะขยายตัวอย่างรวดเร็ว:
- 25182
- 54174
- 109086
- 212766
- 407838
- 773406
- 1455390
- 2721054
ดังนั้นเมื่อเวลาที่แมโครทั้งหมดถูกขยายไฟล์ 295 ไบต์ขนาดเล็กนั้นจะขยายเข้าไปในโค้ดขนาด 2.7 เมกะไบต์ซึ่งต้องถูกคอมไพล์เพื่อสร้างอาร์เรย์ 1024 ไบต์ดั้งเดิม (สมมติว่ามีค่าความยาว 32 บิตที่ไม่ได้ลงชื่อ)!
การแก้ไขอื่น:
ฉันแก้ไขแมโคร C โดยยึดตามแมโครจากคำตอบอื่นเพื่อบีบออกพิเศษ 11 ไบต์และลดขนาดแมโครที่ขยายเต็มได้อย่างมาก แม้ว่า 2.7 MB จะไม่เลวเท่า 54 MB (ขนาดสุดท้ายก่อนหน้าของการขยายแมโครทั้งหมด) แต่ก็ยังมีความสำคัญ