1

I want to convert an array of unsigned char to a signed int! I've already done some try, and the conversion works for the single element like this:

  unsigned char byte[2];
  signed char *valueS[2];
  byte[0] = 0b11110111;
  byte[1] = 0b00001001;

  //Conversion
  for(int i = 0; i < 2; i++)
  {
     valueS[i] = (signed char*)&byte[i];
  }

  //Result
  printf("Val 0 -> %d \n", *valueS[0]); // print -9 Correctly
  printf("Val 1 -> %d \n", *valueS[1]); // print 9 Correctly

  //But when i try to print a 16 bit signed
  printf("Int %d \n", *(signed short*)valueS); //It doesn't work! I expected -2295

How can i get the 16 bit signed int from that unsigned char array? Thank you in advance!

8
  • What is valueS? Commented Jan 11, 2020 at 15:29
  • Assuming valueS is an array of signed char, you don't need all the bother of pointers: just do the direct conversion: printf("Int %d \n", (signed int)valueS[i]);. (Note: you seem to have forgotten to put the i index in!) Commented Jan 11, 2020 at 15:32
  • 2
    0b00001001 not a valid integer literal Commented Jan 11, 2020 at 15:32
  • ...and your solution is machine endianness dependend; Commented Jan 11, 2020 at 15:33
  • //It doesn't work! I expected -2295 - and what's the actual output? Commented Jan 11, 2020 at 15:36

1 Answer 1

2

How can i get the 16 bit signed int from that unsigned char array?

Supposing you mean you want to obtain the int16_t whose representation is byte-for-byte identical to the contents of an arbitrary array of two unsigned char, the only conforming approach is to declare an int16_t object and copy the array elements to its representation. You could use the memcpy() function to do the copying, or you could do it manually.

For example,

#include <stdint.h>

// ...

    unsigned char byte[2] = { 0xF7, 0x05 };
    int16_t my_int;
    unsigned char *ip = (unsigned char *) &my_int;

    ip[0] = byte[0];
    ip[1] = byte[1];
    printf("Int %d \n", my_int);

You might see a recommendation to use a pointer aliasing trick to try to reinterpret the bytes of the array directly as the representation of an integer. That would take a form similar to your code example, but such an approach is non-conforming, and formally it yields undefined behavior. You may access the representation of an object of any type via a pointer to [unsigned] char, as the code in this answer does, but, generally, you may not otherwise access an object via a pointer to a type incompatible with that object's.

Note also that the printf above is a bit sloppy. In the event that int16_t is a different type from int, such as short int, the corresponding printf directive for it will have a length modifier in it -- likely %hd. But because of details of the way printf is declared, it is the result of promoting my_int to int that will be passed to printf. That rescues the mismatch, and in practice, the printed result will be the same as if you used the correct directive.

Sign up to request clarification or add additional context in comments.

3 Comments

Interesting attention to spec with "You might see a recommendation to use a pointer ..." and then casual attention with printf(). Recommend printf("Int %d \n", (int) my_int); or printf("Int %" PRId16 " \n", my_int);
@chux-ReinstateMonica, the code presented in the question is fully conforming, including with respect to the printf call, as already explained in the answer itself. I intentionally chose this approach over the cast and especially over PRId16 so as to avoid distracting the seemingly-inexperienced OP from the details that respond directly to the question. I think throwing in int16_t may have already been a bit challenging.
Thank you all! @JohnBollinger your solution is what I asked for!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.