This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Timer, t1-t0, integral promotion

For ARM7, A hardware timer is 32-bits, and unsigned int is 32-bits too;
For a 16-bits MCU, A hardware timer is 16-bits, and unsigned int is 16-bits too;

So,

t0 = timer_val;
while ( ( timer_val - t0 ) < delay_val );

provide a simple and good delay;

Not so sure about, if a cast is needed.

t0 = timer_val;
while ( (unsigned int)( timer_val - t0 ) < delay_val );

Just noticed that, due to the integral promotion,

unsigned short t0, t1;
( t1 - t0 ) is a signed int.

It seems that,

unsigned int t0, t1;
( t1 - t0 ) is still an unsigned int.

I noticed this, because I use unsigned short to present a 16-bits timer_val on my X86-PC for testing/simulating purpose, and the result is not what I expected.

Parents
  • I am using my stupid way to try to figure out the key point.

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int32_t now = -2147483648, end;
            end = now - 1;
            // while (now - end < 0);
            printf("now = %d\n", now);
            printf("end = %d\n", end);
    
            if ( (int32_t)(now - end) < 0 )
                    printf("Less than 0\n");
            else
                    printf("It is >= Zero\n");
    
            system("PAUSE");
    }
    

    now = -2147483648
    end = 2147483647
    It is >= Zero

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int32_t now = -2147483648, end;
            end = now - 1;
            // while (now - end < 0);
            printf("now = %d\n", now);
            printf("end = %d\n", end);
    
            if ( (now - end) < 0 )
                    printf("Less than 0\n");
            else
                    printf("It is >= Zero\n");
    
            system("PAUSE");
    }
    

    now = -2147483648
    end = 2147483647
    It is >= Zero

    It is the same.

Reply
  • I am using my stupid way to try to figure out the key point.

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int32_t now = -2147483648, end;
            end = now - 1;
            // while (now - end < 0);
            printf("now = %d\n", now);
            printf("end = %d\n", end);
    
            if ( (int32_t)(now - end) < 0 )
                    printf("Less than 0\n");
            else
                    printf("It is >= Zero\n");
    
            system("PAUSE");
    }
    

    now = -2147483648
    end = 2147483647
    It is >= Zero

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int32_t now = -2147483648, end;
            end = now - 1;
            // while (now - end < 0);
            printf("now = %d\n", now);
            printf("end = %d\n", end);
    
            if ( (now - end) < 0 )
                    printf("Less than 0\n");
            else
                    printf("It is >= Zero\n");
    
            system("PAUSE");
    }
    

    now = -2147483648
    end = 2147483647
    It is >= Zero

    It is the same.

Children
  • #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int16_t now = -32768, end;
            end = now - 1;
            // while (now - end < 0);
            printf("now = %d\n", now);
            printf("end = %d\n", end);
    
            if ( (int16_t)(now - end) < 0 )
                    printf("Less than 0\n");
            else
                    printf("It is >= Zero\n");
    
            system("PAUSE");
    }
    

    now = -32768
    end = 32767
    It is >= Zero

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int16_t now = -32768, end;
            end = now - 1;
            // while (now - end < 0);
            printf("now = %d\n", now);
            printf("end = %d\n", end);
    
            if ( (now - end) < 0 )
                    printf("Less than 0\n");
            else
                    printf("It is >= Zero\n");
    
            system("PAUSE");
    }
    

    now = -32768
    end = 32767
    Less than 0

    It is different.

  • It is different.

    No wonder.
    When you are doing ( (now - end) < 0 ), the 16-bit signed integers are promoted to 32-bit ones prior to subtraction, so an overflow is no longer possible. Hence, the result is negative.
    When you are doing ( (int16_t)(now - end) < 0 ), you are converting the result of subtruction (which is -65535 or 0xFFFF0001) to int16_t. The conversion simply throws away the upper 16 bits, so you are left with 0x0001 which is positive.

  • @John Linq,

    You are _not_ stupid and you are certainly _not_ an idiot !