ในคำตอบนี้ , zwolทำให้การเรียกร้องนี้:
วิธีที่ถูกต้องในการแปลงข้อมูลสองไบต์จากแหล่งข้อมูลภายนอกให้เป็นจำนวนเต็ม 16 บิตที่มีลายเซ็นคือฟังก์ชันผู้ช่วยเช่นนี้
#include <stdint.h>
int16_t be16_to_cpu_signed(const uint8_t data[static 2]) {
uint32_t val = (((uint32_t)data[0]) << 8) |
(((uint32_t)data[1]) << 0);
return ((int32_t) val) - 0x10000u;
}
int16_t le16_to_cpu_signed(const uint8_t data[static 2]) {
uint32_t val = (((uint32_t)data[0]) << 0) |
(((uint32_t)data[1]) << 8);
return ((int32_t) val) - 0x10000u;
}
ฟังก์ชันข้างต้นใดที่เหมาะสมขึ้นอยู่กับว่าอาเรย์นั้นประกอบไปด้วย endian เพียงเล็กน้อยหรือการแสดง endian ขนาดใหญ่ endianness ไม่เป็นปัญหาที่คำถามที่นี่ผมกำลังสงสัยว่าทำไมzwolหัก0x10000u
จากค่าแปลงuint32_t
int32_t
เหตุใดจึงเป็นวิธีที่ถูกต้อง ?
มันจะหลีกเลี่ยงพฤติกรรมที่กำหนดโดยการนำไปปฏิบัติเมื่อแปลงเป็นชนิดส่งคืนได้อย่างไร
เนื่องจากคุณสามารถสันนิษฐานได้ว่าการเป็นตัวแทน 2 นั้นจะทำให้การโยนง่ายขึ้นอย่างไร: return (uint16_t)val;
เกิดอะไรขึ้นกับโซลูชันไร้เดียงสานี้:
int16_t le16_to_cpu_signed(const uint8_t data[static 2]) {
return (uint16_t)data[0] | ((uint16_t)data[1] << 8);
}
int16_t
0xFFFF0001u
ไม่สามารถแทนได้int16_t
และในวิธีที่สอง0xFFFFu
จะไม่สามารถแทนint16_t
ได้
int16_t
ใช้เป็นการกำหนดการใช้งานดังนั้นวิธีการที่ไร้เดียงสาจึงไม่สามารถพกพาได้