8 bit signed overflowing problem Topic is solved

If you have a simple question and just want an answer.
Post Reply
User avatar
aclassifier
Respected Member
Posts: 483
Joined: Wed Apr 25, 2012 8:52 pm
Contact:

8 bit signed overflowing problem

Post by aclassifier »

I have discovered a problem with some signed 8 bit code. As far as I can tell a code example in http://www.teigfam.net/oyvind/home/tech ... g_surprise (disclaimer: no money with this or any other of my links) fails:

Code: Select all

unsigned int  Cnt1 = 0; // 16 bits (kind of system clock)unsigned int  Cnt2 = 0; // 16 bits (observer)signed   char Timer_Secs = 0;             // 8 bits with signsigned   char FutureTimeout_1Minute = 60; // 8 bits with signwhile (Cnt1 < 602) { //                      ##    if ((Timer_Secs - FutureTimeout_1Minute) == 0) {                    FutureTimeout_1Minute += 60; // Overflow/underflow allowed,                                      // so wraps and changes sign         Cnt2++;     } else {} // No code    Timer_Secs++;     Cnt1++;} //               ## // Cnt2 is 35 if >  0 above   #define AFTER_F(a,b)    ((a-b)>0)// Cnt2 is 35 if >= 0 above   #define AFTER_EQ_F(a,b) ((a-b)>=0)// Cnt2 is 10 if == 0 above   #define AFTER_ON_F(a,b) ((a-b)==0) //         10 is expected
It also fails in xTIMEcomposer. Or is this correct in any way? Why is it compiled like this and what is the "solution"? 

Is the XMOS GCC-based?

It works as expected in Go, see my blog note or http://play.golang.org/p/lH2SzZQEHG



--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
View Solution
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

My interpretation of what you are trying to do is as follows: implement a comparison function that returns whether the first timer value was sampled after the second, assuming that the first timer value was sampled no more than 128 timer ticks before / 127 timer ticks after the second value.

Consider AFTER_F(-128, 127). This should evaluate to true since -128 is only one timer tick after 127. However if you expand your definition of the macro you get:

-128 - 127 > 0

Which is equivalent to

-255 > 0

Which evaluates to false. A correct implementation of AFTER_F is as follows:

#define AFTER_F(a, b) ((signed char)(a-b)>0)

Now AFTER_F(-128, 127) expands to:

(signed char)(-128 - 127) > 0

Which is equivalent to

(signed char)-255 > 0

Which is equivalent to

1 > 0

Which evaluates to true.

In C when you have an expression such as (a - b), a and b are converted to type int before the subtraction is performed (these rules are known as the usual arithmetic conversions). if you want the result to have type signed char you need an explicit cast. The rules in Go are different, in particular the result type of an arithmetic operator is the same as the type of its first operand so no explicit cast is needed.

Post Reply