My short int likes 0xffff9001 
Author Message
 My short int likes 0xffff9001

Hello. I have a bizarre problem dealing with converting an int to a
short int.  I read a line from my datafile(ex 1.1) as an int (in hex)
and attempt to format it into a short int.  When I do this, I get what
looks like bizarre integral promotion in the output of UNIT.Whole and
HOUSE.Whole.  I should point out, that I am attempting to mask out the
upper bits, but I still get shot in the foot and the (so labeled) really
important sprintf statement produces 0xffff9001 for UNIT.Whole and
0xffff8002 for House.Whole.

I should note that it is important that I use the union to do this...
and that even if I just define UNIT a short int (removing the unions)
that I receive similar bad answers.

Any help would be appreciated.  Look at the code carefully...

Benjamin G. Haupt
Foster-Miller, Inc.
Staff Engineer

ex 1.1
/* Typical Datafile line */
  // UNIT               // HOUSE        // IGNORE
  0x9001                0x8002          0x0000000000000000000

I have defined a macro D_PRINT and a union in the header file.

ex 1.2
/* FROM THE .h FILE */

#ifdef DEBUG
#define D_PRINT(x) fprintf(stderr, "DEBUG: %s\n", x); fflush(stderr);
#else
#define D_PRINT(x)
#endif

typedef union
{
  unsigned char SigByte[2];
  /* SigByte[0] LSB
     SigByte[1] MSB */
  short int Whole;

Quote:
} ConvByte;

In my main routine...

ex 1.3
/* FROM THE .c FILE */
    for(int i = 0; i<n; i++)
    {
        int t_unit;
        ConvByte UNIT;
        int t_house;
        ConvByte HOUSE;

        GetLine(address_list, buffer);// Reads a line from datafile
                                      // places it in buffer
                                      // omitted for conciseness
        sscanf(buffer, "%x\t%x", &t_unit, &t_house);
        D_PRINT(buffer);

        /* REALLY IMPORTANT LINES */
        UNIT.Whole = (short int)(t_unit & 0x0000FFFF);
        HOUSE.Whole = (short int)(t_house & 0x0000FFFF);
        sprintf(debug_msg,"%#04x %#04x", UNIT.Whole, HOUSE.Whole);
        /*  END REALLY IMPORTANT LINES */

        D_PRINT(debug_msg);
        sprintf(debug_msg,"%#02x %#02x",UNIT.SigByte[0],
                UNIT.SigByte[1]);
        D_PRINT(debug_msg);
    }



Tue, 03 Sep 2002 03:00:00 GMT  
 My short int likes 0xffff9001

Quote:

> Hello. I have a bizarre problem dealing with converting an int to a
> short int.  I read a line from my datafile(ex 1.1) as an int (in hex)
> and attempt to format it into a short int.  When I do this, I get what
> looks like bizarre integral promotion in the output of UNIT.Whole and
> HOUSE.Whole.  I should point out, that I am attempting to mask out the
> upper bits, but I still get shot in the foot and the (so labeled) really
> important sprintf statement produces 0xffff9001 for UNIT.Whole and
> 0xffff8002 for House.Whole.

When a short is passed as a varargs argument, it is automatically
promoted to int, retaining its value.  Since you're apparently
using a 2's-complement machine, this means that 0x9001 becomes
0xffff9001.  If you want it to become 0x00009001 instead, then
cast it to unsigned short in the call.


Tue, 03 Sep 2002 03:00:00 GMT  
 My short int likes 0xffff9001
...

Quote:
>typedef union
>{
>  unsigned char SigByte[2];
>  /* SigByte[0] LSB
>     SigByte[1] MSB */
>  short int Whole;
>} ConvByte;
...
>        /* REALLY IMPORTANT LINES */
>        UNIT.Whole = (short int)(t_unit & 0x0000FFFF);
>        HOUSE.Whole = (short int)(t_house & 0x0000FFFF);
>        sprintf(debug_msg,"%#04x %#04x", UNIT.Whole, HOUSE.Whole);
>        /*  END REALLY IMPORTANT LINES */

[The cast to (short int) in the assignments is unnecessary; the assignment
automatically performs the conversion.]

Assuming that your implementation-dependent assumptions are correct, and
that sizeof(short int) == 2 and CHAR_BIT == 8, the problem is that you're
putting negative numbers in UNIT.Whole and HOUSE.Whole, and when they're
passed as arguments to sprintf, and get promoted to int, they retain their
negative values.  I predict that on your machine,
   #include <stdio.h>
   #include <limits.h>
   int main(void) { printf("%d\n", SHRT_MAX); return 0; }
will print the value 32767.  0x9001 == 36865, which is greater than
SHRT_MAX, and assigning it to a short int doesn't produce the results you
expect.  Probably the best thing for you to do is to change the declaration
of Whole from (short int) to (unsigned short int).  The other thing which
will fix the immediate problem is to change the REALLY IMPORTANT sprintf to
    sprintf(debug_msg,"%#04x %#04x",
            UNIT.Whole & 0xFFFF, HOUSE.Whole & 0xFFFF);

--

Kenan Systems Corp., a wholly-owned subsidiary of Lucent Technologies



Tue, 03 Sep 2002 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. different between short int and int

2. cast long int to short int

3. short int vs int wrt to execution time

4. Int,short int and portability of code

5. short vs int

6. short to int conversion

7. DWORD, int, short, and long

8. Finding the respective upper and lower bytes in memory of a short unsigned int

9. convert char to short int via pointer?...

10. comparing int and unsigned short

11. bytes to unsigned char, unsigned short, unsigned int, ...

12. short int and %hd

 

 
Powered by phpBB® Forum Software