![](/img/trans.png)
[英]How to convert an unsigned 24 bit int into a signed int and sign extend to 32 bits?
[英]Convert 8 bit signed integer to unsigned and then convert to int32
我有一個有符號的 8 位整數( int8_t
)——它可以是從-5
到5
任何值——並且需要將它轉換為一個無符號的 8 位整數( uint8_t
)。
這個uint8_t
值然后被傳遞到另一個硬件(只能處理 32 位類型)並且需要轉換為int32_t
。
我怎樣才能做到這一點?
示例代碼:
#include <stdio.h>
#include <stdint.h>
void main() {
int8_t input;
uint8_t package;
int32_t output;
input = -5;
package = (uint8_t)input;
output = (int32_t)package;
printf("output = %d",output);
}
在這個例子中,我從-5
開始。 它暫時被強制轉換為251
因此可以將其打包為uint8_t
。 然后將此數據發送到另一塊硬件,在那里我不能使用(int8_t)
在轉換為int32_t
之前將 8 位無符號整數轉換回有符號整數。 最終,我希望能夠獲得原始的-5
值。
有關更多信息,接收硬件是不允許int8_t
的 SHARC 處理器 - 請參閱https://ez.analog.com/dsp/sharc-processors/f/qa/118470/error-using-stdint-h-types
SHARC 處理器上的最小可尋址內存單元是 32 位,這意味着任何數據類型的最小大小都是 32 位。 這適用於像 char 和 short 這樣的原生 C 類型。 由於類型“int8_t”、“uint16_t”指定類型的大小必須分別為 8 位和 16 位,因此 SHARC 不支持它們。
如果您想使用 32 位操作取回負號,您可以執行以下操作:
output = (int32_t)package;
if (output & 0x80) { /* char sign bit set */
output |= 0xffffff00;
}
printf("output = %d",output);
由於您的接收器平台沒有小於 32 位寬的類型,因此您最簡單的選擇是在發送器上解決此問題:
int8_t input = -5;
int32_t input_extended = input;
uint8_t buffer[4];
memcpy(buffer, &input_extended, 4);
send_data(buffer, 4);
然后在接收端,您可以簡單地將數據視為單個int32_t
:
int32_t received_data;
receive_data(&received_data, 4);
所有這些都假設您的發送方和接收方共享相同的字節序。 如果沒有,您必須在發送之前翻轉發送方的字節序:
int8_t input = -5;
int32_t input_extended = input;
uint32_t tmp = (uint32_t)input_extended;
tmp = ((tmp >> 24) & 0x000000ff)
| ((tmp >> 8) & 0x0000ff00)
| ((tmp << 8) & 0x00ff0000)
| ((tmp << 24) & 0xff000000);
uint8_t buffer[4];
memcpy(buffer, &tmp, 4);
send_data(buffer, 4);
只需從值中減去 256 ,因為在2 的補碼中,n 位負值v存儲為2 n - v
input = -5;
package = (uint8_t)input;
output = package > 127 ? (int32_t)package - 256 : package;
這是一種可能的無分支轉換:
output = package; // range 0 to 255
output -= (output & 0x80) << 1;
如果設置了第 7 位,第二行將減去 256,例如:
編輯:
如果問題是您的代碼具有值-5
到5
if
語句,那么最簡單的解決方案可能是測試result + 5
並將if
語句更改為0
到10
之間的值。
這可能是編譯器在優化時會做的事情(因為 0-10 的值可以轉換為映射,避免if
語句並最小化預測性 CPU 刷新)。
原來的:
如果首先轉換為uint8_t
然后uint32_t
...
output = (int32_t)(uint32_t)(uint8_t)input;
當然,如果第 8 位被設置,它將保持設置,但符號不會被擴展,因為類型轉換操作告訴編譯器將第 8 位視為常規位(它是無符號的)。
當然,如果你想更嚴格,你總是可以享受位掩碼的樂趣,但這本質上是一種浪費或 CPU 周期。
編碼:
#include <stdint.h>
#include <stdio.h>
void main() {
int8_t input;
int32_t output;
input = -5;
output = (int32_t)(uint32_t)(uint8_t)input;
printf("output = %d\n", output);
}
結果為“ output = 251
”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.