ইন এই উত্তর , 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;
}
উপরের ফাংশনগুলির মধ্যে কোনটি উপযুক্ত তা অ্যারেতে একটু এন্ডিয়ান বা বড় এন্ডিয়ান উপস্থাপনা রয়েছে কিনা তার উপর নির্ভর করে। এডিয়েননেস এখানে প্রশ্নটি নয়, আমি ভাবছি কেন 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
বাস্তবায়ন-সংজ্ঞায়িত হয়, তাই নিখুঁত দৃষ্টিভঙ্গি পোর্টেবল হয় না।