Society of Robots - Robot Forum

Software => Software => Topic started by: Resilient on March 18, 2009, 05:05:09 PM

Title: C math questoin
Post by: Resilient on March 18, 2009, 05:05:09 PM
Ok so I got this:

Code: [Select]
const int PERIOD_NORMAL = 10; //brings the error down to something the controller can deal with
volatile uint16_t r_period = 0; //time between right clicks

void do_some_math(int right_target)
    int r_error = 0;
    r_error = (right_target/PERIOD_NORMAL - r_period/PERIOD_NORMAL);
    rprintf("r_error: %d\n",r_error);

If I call this all is well and r_error can be negative.

Code: [Select]
r_error = (right_target/PERIOD_NORMAL - r_period/PERIOD_NORMAL);
is changed to
Code: [Select]
r_error = (right_target - r_period)/PERIOD_NORMAL;
r_error can no longer be negative. If it should be negative, it will instead become some number around 16000.

What C voodoo is going on here?
Title: Re: C math questoin
Post by: paulstreats on March 18, 2009, 07:31:12 PM
its converting it to an unsigned int.

signed int range -16000 to 16000

unsigned int range 0 to 32000

as you can see a signed int with a value of 0 would convert into an unsigned int with a value of 16000

Because you just declared r_error as an int, the compiler will see this as unsigned meaning that you are telling it to only work within the range of 0 and 32000. The first calculation(the one you think is working right) is actually working wrong. because r_period isnt a seperate bracketed calculation it converts r_error to unsigned (because the unsigned int dont go beyond a signed int scope, it converts the original int declaration for continuity).

The second calculation keeps right_target/r_period in seperate brackets so it maintains the original declaration of an int. (when you dont specify most compilers default to unsigned). so the second calculation is doing nothing out of the ordinary.

a way to solve it is to use unsigned int for everything to do with this calculation or you could do something like:

                  start by declaring r_error as signed int and not just int
                  r_error = (signed int)((right_target - r_period)/PERIOD_NORMAL);

**where it says "signed int" in the brackets you should put your c syntax for declaring a signed int there.(in my comiler I would just put "signed int" but your compiler may need something different)

By putting (signed int) you are telling the compiler to return the product of the sum as a signed int
Title: Re: C math questoin
Post by: Resilient on March 19, 2009, 01:13:35 AM
Huh, unsigned is the default? I was thinking signed was default... Python has made me complacent when it comes to variables.  :P