This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problem with cast from double to unsigned short int

A very similar question was answered on this list by Ian Lance Taylor on 3/24/2010. He wrote:

The C99 standard says that when converting floating point to integer,
the value is first truncated toward zero.  If the value of the
integral part cannot be represented by the integer type, the behaviour
is undefined.  This means that converting a negative floating point
value<= -1.0 to an unsigned integer type is undefined, and the code
may act unpredictably.

In your code, casting to a double yields 52536.0. Since this is not in the range -32768 to +32767 the cast to short int is undefined. So all bets are off.

I responded on 3/29:

I think this is a good illustration of why one should not use type casting to perform algorithmic operations. You should operate on the data and test the resulting value to ensure it will fit within the new type.

I'm a big fan of writing code that explicitly shows each step in an algorithm one statement at a time. If the operations are in a loop, and testing shows that the loop is slowing things down too much, then obscure and tricky code may be in order, but only with good commenting. The maintenance programmer, perhaps you at a later date, will appreciate being able to follow simple code.


On 4/14/2010 11:31 AM, Gederberg, Thomas K wrote:
I am having an interesting problem when casting from double to an unsigned short int as shown in the following example:.


int main()
    unsigned short int ius;
    unsigned short int ous;
    short int is;

ius = 52536;

is = (short int) ((double)(ius));

ous = (unsigned short int) is;

    printf("ius = %hu\n", ius);
    printf("is  = %d\n", is);
    printf("ous = %hu\n", ous);

Using a Sun CC compiler and Microsoft Visual C++ for 32-bit, the above code generates:

ius = 52536
is  = -13000
ous = 52536

which is as I would expect. The two's complement of 52536 is -13000.

However, when compied using gcc (version 3.2.3, also confirmed with gcc 4.4.1) with the -m32 option specifed, the code produces:

ius = 52536
is  = -32768
ous = 32768

Is this a bug with gcc? Also, if I don't cast ius to (double) before casting to (short int), I get what I expect. Can anyone explain?


Note: this problem popped up in some code I am trying to port from Solaris to Linux. The code includes the following macro:
#define REAL_TO_SHORT_BIT_TYPE(X) ((unsigned short int) ((short int) ((double) (x))))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]