Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

160
Visualizações
Correct interpretation signed vs unsigned

I'm receiving 2 bytes from a communication and then i need to merge these 2 values to obtain a 16 bit value.

Now suppose that I expect to receive the number 200, then the two characters are a and b

char a=0x00;
char b=0xc8;
int  cw = (a << 8) | b ;
printf("cw= %d\n",cw);

Doing the merge the variable cw becomes -56 instead of 200

If i change char by unsigned char i got the correct value 200 How can i fix that? i expect to receive both positive and negative numbers and of course the number 200

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

The C standard essentially provides no way to shift a 1 bit into or out of the sign position (the only defined cases for << are for non-negative values that do not overflow) and no definite way to convert an unsigned value to a negative value (conversions of out-of-range values to signed integer types are implementation-defined).

So we should not use a shift. However, multiplication of negative values is of course defined, so we can use:

int8_t  a;
uint8_t b;
// Put code here to receive a and b by some method.
uint16_t cw = a*256 + b;

If you must reconstruct the signed integer from unsigned types, then an option is to test the sign bit and apply the two’s complement manually:

unsigned char a, b;
// Put code here to receive a and b by some method.
int cw = (a & 0x7f) << 8 | b;  // Assemble the low 15 bits.
if (a & 0x80)
    cw += -128*256;            // If sign bit is set, adjust.

You can also copy the bits in:

unsigned char a, b;
// Put code here to receive a and b by some method.
int16_t cw;
memcpy(&cw, (uint16_t []) { (uint16_t) a << 8 | b }, sizeof cw);

(The above presume your 16-bit integer uses two’s complement.)

over 4 years ago · Santiago Trujillo Relatório

0

16 bit value.

Just use proper type.

unsigned char a = 0x00;
unsigned char b = 0xc8;
int16_t cw = ((unsigned int)a << 8) | b;
over 4 years ago · Santiago Trujillo Relatório

0

The only change you should do is defining the least significant byte unsigned:

char a;
unsigned char b;
... // receive a and b from your communication
int cw = (a << 8) | b;
printf("cw = %d\n", cw);

The arithmetic/logic expression should work, but it may be non-trivial to explain why it doesn't overflow, because it involves promotion of char or unsigned char to int (which, I guess, is 16-bit on your system).

If you want your code to be portable (i.e. not assume 16-bit int or any other property of your specific platform), use integers with defined size, and do explicit casting.

int8_t a;
uint8_t b;
... // receive a and b from your communication
int16_t cw = (int16_t)((int16_t)a << 8) | (int16_t)b;
printf("cw = %d\n", (int)cw);

But this code is less readable, so I am not sure being more portable has any advantage here.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda