[英]How to store a *signed* 24 bit int into another variable?
我需要將24位整數編碼為32位int的末尾。
(第一個字節包含其他數據,其他三個字節為24位int使用為空)
我已經有一個SET_BYTE
宏,並且可以成功地對無符號的 24位值執行以下操作:
SET_BYTE(DEST, START_BYTE_INDEX, (uint8_t)(VALUE));
SET_BYTE(DEST, START_BYTE_INDEX+1, (uint8_t)(VALUE >> 8));
SET_BYTE(DEST, START_BYTE_INDEX+2, (uint8_t)(VALUE >> 16));
我堅持認為的是,我不確定如何修改此方法以用於帶符號的 24位整數嗎?
例如,如果我嘗試使用上述值存儲值-22(顯然已修改為使用int8_t
), int8_t
得到以下字節值:
-22
-1
-1
讀回這些內容(如果我在閱讀時執行<<0
, <<8
和<<16
):
-22
-256
-65536
我假設我只需要完全避免帶符號值的這些偏移,但是我不確定什么是正確的方法?
如果需要≥32位的結構(如您所說,最后一個字節中還有其他數據),請使用struct位域:
struct Packed
{
uint8_t byte;
int32_t smaller : 24;
};
或者,您可以濫用std::bitset
:
struct fake_int24_t
{
static_assert(sizeof(int) <= sizeof(unsigned long long), "");
bitset<24> data;
operator int() const {
return data.to_ulong() - (1 << 23);
}
fake_int24_t& operator=(int val) {
assert(val >= -(1 << 23)); // 2's complement
assert(val < (1 << 23));
data = bitset<24>(val + (1 << 23));
return *this;
}
};
sizeof(fake_int24_t)
不必為3,因此您可能需要在其中粘貼一個普通整數。
將24位整數編碼為32位int的末尾。
OP的現有宏表示24位無符號類型存儲在little endian中-請參見下文。
讓我們假設24位帶符號使用相同的字節序和公共2的補碼整數編碼。
SET_BYTE(DEST, START_BYTE_INDEX, (uint8_t)(VALUE));
SET_BYTE(DEST, START_BYTE_INDEX+1, (uint8_t)(VALUE >> 8));
...
請注意,我們不知道32位int
的字節序,也不知道其編碼(2,1或正負號)。 事實證明,我們不需要該信息。
struct signed_24_bit {
uint8_t other_data;
uint8_t use_by_the_24_bit_int[3];
};
int decode_24_bit_integer(struct signed_24_bit x) {
int32_t y = x.use_by_the_24_bit_int[0] // 1st byte of int24
+ (x.use_by_the_24_bit_int[1] * 0x100)
+ (x.use_by_the_24_bit_int[2] * 0x10000);
// If y > INT24_MAX
if (y > 0x7FFFFF) y -= 0x1000000;
return y;
}
// Assume `x` is in range of `int24_t`
struct signed_24_bit encode_24_bit_integer(int x) {
if ( x < 0) x += 0x1000000;
struct signed_24_bit y = { 0, { x, x/0x100, x/0x10000 } };
return y;
}
我會在24位部分使用符號幅度表示:
int value = -22;
unsigned long target = std::abs(value) & ((1 << 23) - 1);
if (value < 0)
target |= 1 << 23;
要提取值,只需逆轉過程即可:
int result = target & ((1 << 23) - 1);
if (target & (1 << 23))
result = -result;
(警告:未經測試)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.