This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

change a int (4 char) to 4 short



Hi..

I have a int variable like this:

int IntVal = 0xff0102fa;

and I wnat to change it on 4 short like this:

short S1,S2,S3,S4;

S1 = 0xffff;

S2 = 0x0001;

S3 = 0x0002;

S4 = 0xfffa;

I don't like this solution:

 

int IntVal = 0xff0102fa;

char *CharPtr;

CharPtr = (char *)(&IntVal );

S1 = CharPtr[0] ; etc

 

any suggestion?

thanks

PF

 

  • Consider:

    #define EXTRACT(i,b) ((((i) << ((3-(b))*8)) >> (3*8)) & 0xffff)
    S1 = EXTRACT(IntVal, 3);
    S2 = EXTRACT(IntVal, 2);
    S3 = EXTRACT(IntVal, 1);
    S4 = EXTRACT(IntVal, 0);
  • It is useful to know that this ...

    PF Melamed84061 said:
    CharPtr = (char *)(&IntVal );

    is called type punning.  Do an internet search on that term.  It is generally a bad thing, and is to be used only as a very last resort.

    Thanks and regards,

    -George

  • Looks like the requirement to sign extend 8 to 16 bits is what makes this a bit complicated. Here's a shift, truncate and signed extend by assignment approach:

    void extract(int i, short v[])
    {
      char x;
      x    = (char)i; // Truncate to 8 bits.
      v[3] = x;       // Assign and sign extend, LSB
      i  >>= 8;       // Shift down next byte
      x    = (char)i; // Truncate to 8 bits.
      v[2] = x;       // Assign and sign extend
      i  >>= 8;       // Shift down next byte
      x    = (char)i; // Truncate to 8 bits.
      v[1] = x;       // Assign and sign extend
      i  >>= 8;       // Shift down next byte
      x    = (char)i; // Truncate to 8 bits.
      v[0] = x;       // Assign and sign extend, MSB
    }

    Assumes char is really 8 bits, short is 16 bits and int is 32 bits. Wait for the usual noise about using stdint.h.

    The method suggested by Archaeologist is shift left to MSB, sign replicate by arithmetic shift right and assign. The C6000 series has an intrinsic for this. In theory, the compilar might optimize this to the intrinsic. Or explicitly use the intrinsic.

    void extract(int i, register short *v)
    {
      v[3] = (short)_ext(i, 24, 24); // LSL 24, ASL 24, truncate to 16 bits, LSB
      v[2] = (short)_ext(i, 16, 24); // LSL 16, ASL 24, truncate to 16 bits
      v[1] = (short)_ext(i,  8, 24); // LSL  8, ASL 24, truncate to 16 bits
      v[0] = (short)_ext(i,  0, 24); // LSL  0, ASL 24, truncate to 16 bits, MSB
    }

    Another method is to use a union of structures.

    typedef union
    {
      int  i;
      char b[4];
    } CONVTYPE;

    void extract(int i, short v[])
    {
      CONVTYPE t;
      t.i  = i;
      v[3] = t.b[0]; // Sign extend 8 to 16 and assign. LSB
      v[2] = t.b[1]; // Sign extend 8 to 16 and assign
      v[1] = t.b[2]; // Sign extend 8 to 16 and assign
      v[0] = t.b[3]; // Sign extend 8 to 16 and assign, MSB
    }

    This method assumes much. The structure must be packed. The code assumes that the processor is little endian.

     

  • Thanks..

    I take this solution...

    void extract(int i, register short *v)
    {
      v[3] = (short)_ext(i, 24, 24); // LSL 24, ASL 24, truncate to 16 bits, LSB
      v[2] = (short)_ext(i, 16, 24); // LSL 16, ASL 24, truncate to 16 bits
      v[1] = (short)_ext(i,  8, 24); // LSL  8, ASL 24, truncate to 16 bits
      v[0] = (short)_ext(i,  0, 24); // LSL  0, ASL 24, truncate to 16 bits, MSB
    }

    And is good for translate 4 char to 4 int ...

    Thanks again

    PF

  • Oops. Noticed the comments were wrong. Should be ASR not ASL.

    void extract(int i, register short *v)
    {
      v[3] = (short)_ext(i, 24, 24); // LSL 24, ASR 24, truncate to 16 bits, LSB
      v[2] = (short)_ext(i, 16, 24); // LSL 16, ASR 24, truncate to 16 bits
      v[1] = (short)_ext(i,  8, 24); // LSL  8, ASR 24, truncate to 16 bits
      v[0] = (short)_ext(i,  0, 24); // LSL  0, ASR 24, truncate to 16 bits, MSB
    }

    Not sure about using this to convert 4 char to 4 int. That should a plain assignment from char to int (sign extends automatically).