簡體   English   中英

將 8 位有符號整數轉換為無符號整數,然后轉換為 int32

[英]Convert 8 bit signed integer to unsigned and then convert to int32

我有一個有符號的 8 位整數( int8_t )——它可以是從-55任何值——並且需要將它轉換為一個無符號的 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,例如:

  • 251 設置了第 7 位,251 - 256 = -5
  • 5 清除第 7 位,5 - 0 = 5

編輯:

如果問題是您的代碼具有值-55 if語句,那么最簡單的解決方案可能是測試result + 5並將if語句更改為010之間的值。

這可能是編譯器在優化時會做的事情(因為 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM