Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

156
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!