Home > Enterprise >  strange behaviour in C ? operations priority
strange behaviour in C ? operations priority

Time:06-21

I tested the following instruction which gives me a wrong result :

float tmp = 26.75   (data[8]   (((SHORT) data[9]) << 8)) * 0.125 / 64;

Then, I tried to separate this instruction in two and it works :

SHORT ee =  (data[8]   (((SHORT) data[9]) << 8));                                                                                      
float tmp = 26.75   ee * 0.125 / 64; 

I don't understand why this happens.

first_version:

float get_TMP () {
    float tmp = 26.75   (data[8]   (((SHORT) data[9]) << 8)) * (0.125) / 64;
    return tmp;
}

last_version :

float get_TMP () {
    SHORT ee =  (data[8]   (((SHORT) data[9]) << 8)); 
    float tmp = 26.75   ee * (0.125) / 64;
    return tmp;
}

and data is :

unsigned char data[10];

Here are the results :
(old) celsius is the result for the "last_version" (ok)
(new) celsius is the result for the "first_version" (error)

enter image description here

CodePudding user response:

In general, you should be very careful mixing signed integer types and unsigned integer types. In your example, you could also use signed char. However, it is hard to say whether this is what you want.

Assume data[8] = data[9] = 0xFF, char is unsigned, SHORT is signed short, which is 16 bit, and signed int is 32 bit. Then you compute (the u after a constant means that the type is unsigned):

0xFFu   (((signed short) 0xFFu) << 8)
=
0xFFu   (0x00FF << 8)
= (integral promotion)
0xFFu   (0x000000FF << 8)
=
0xFFu   0x0000FF00
= (integral promotion)
0x000000FFu   0x0000FF00u
=
0x0000FFFFu (an unsigned and positive number)

In the first example, you directly convert this number to float and get a positive number.

In the second example, you convert this number to signed short and obtain 0xFFFF and then back to signed int and obtain 0xFFFFFFFF (a signed negative number). Then you convert it to float and obtain a negative number.

  •  Tags:  
  • c
  • Related