Signed char conversion



  • Hi
    This code gives 'c' a value of 8
    @
    signed char c = 127;
    c = (c + 4) / 16;
    @

    But this code gives -127
    @
    signed char c = 127;
    c = (c + 4);
    c = c / 16;
    @

    This code gives also 8
    @
    signed char c = 127;
    c = (c + 4) / (signed char)16;
    @

    This code gives also 8
    @
    signed char c = 127;
    signed char x = 4;
    signed char y = 16;

    c = (c + x) / y;
    @

    Could someone please explain why this is so

    Thanks



  • Hi,

    each compiler optimizes written code in order to reduce single CPU operations.
    Probably if you do a single calculation (example 1, 3 e 4) compiler makes optimization and avoid overflow problem identified in case 2.

    However the correct result should be -8 because your code generates an overflow.

    Regards



  • The correct result would not be -8 for example 2,
    c = 127; // 127
    c += 4; // 131 --> overflow = -125
    c /= 16; // -7

    How the compiler caches temporaries in between, you never know.
    it might be in example 1, that the temp value is stored as int as this is the prefered size on a 32 bit processor.

    In your example 2, you do not work with temporaries but store the result always in the signed int. so You get the overflow problem.

    This was the test code in the debugger:

    @
    signed char c = 127;
    c += 4;
    c /= 16;
    @


  • Moderators

    You need to remember that literals like 4 or 16 are signed integers. This is given by the standard.
    @
    4 // int
    4u // unsigned int
    4l // long
    4ul // unsigned long
    ...
    @
    So:
    @
    (c + 4) // c is signed char, 4 is signed integer so a widening conversion is done
    ((int)c + 4) // this is equivalent

    c = (c + 4) // c is signed char, (c + 4) is signed integer, narrowing result to fit
    c = (signed char)(c + 4) //this is equivalent

    (c + 4) / 16 // (c + 4) is signed integer, 16 is signed integer, no conversion
    c = (c + 4) / 16 // (c + 4) / 16 is signed integer, c is signed char, narrowing
    c = (signed char)((c + 4) / 16) // this is equivalent
    @
    ...and so on.

    Reasoning the code like this you will see that your narrowing conversions occur in different places, rendering different results.
    As a side note:
    @//those are equivalent
    (c + 4) / (signed char)16
    ((int)c + 4) / (int)(signed char)16
    @
    so the explicit cast to signed char is pointless as it will be cast back again.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.