New to C Please help !

For C and ASSEMBLY users to post questions and code snippets for programming in C and ASSEMBLY. And for any other C or ASM course related questions.

Moderators: Benj, Mods

Post Reply
iain wilkie
Posts: 97
Joined: Tue Jul 14, 2009 4:37 pm
Has thanked: 13 times
Been thanked: 9 times
Contact:

New to C Please help !

Post by iain wilkie »

This will probably have you all laughing but I am stuck ....

I need to do a calculation that needs long integers. It also involves a Flowcode variable I will call TESTNO.
Now TESTNO is a defined variable in me Flowcode BUT it is only an integer (16 bit)
TESTNO can never be any larger than 9999.

What I need to do is multiply TESTNO by a 3192 and then divide by 100000. As you will see the result will always fit
into a 16 bits. However the arithmetics dictate we need more that 16 bits ... hence the need for long.

I note this cannot be done directly in Flowcode, so my C code box is as follows....

unsigned long int var;
var = (FCV_TESTNO * 3192)/100000;
FCV_TESTNO = var;

No matter what the value of TESTNO is the result is always 0. Can you tell me what I am doing wrong ... I have a funny feeling
it has something to do with the last line where I am reading a 32 bit result into a 16 bit variable ??? .... how are you meant to do this ??

Sorry

Iain

Now tried this ...

unsigned long int var;
var = (100000 * 3129)/100000;
FCV_REACTION_TIME = (unsigned short int) var;

This returns an answer of 3192 (great), but if I now change it to ....

unsigned long int var;
var = (10000 * 3129)/10000;
FCV_REACTION_TIME = (unsigned short int) var;

I get an answer of 2 !!!!

Where am I going wrong ?

User avatar
Steve
Matrix Staff
Posts: 3424
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Re: New to C Please help !

Post by Steve »

I don't know if this will help. It's from the BoostC manual:
Operators
If an operation result is not explicitly casted, it is promoted by default to 16 bit
precision. For example, given the following expression:

Code: Select all

long l = a * 100 / b; //'a' and 'b' are 16 bit long variables
the result of the multiplication will be stored in a 16-bit long (word) temporary
variable, that will be then divided by b. This 16-bit long result will eventually be
stored in l. This is the ANSI 'C' standard behavior.
This behavior can be changed using the -Op compiler command line option or a
local #pragma OPTIMIZE directive.
When this optimization is applied to the given expression, the multiplication result
will be promoted to 32-bit long (dword) temporary variable, that will then be
divided by b: the result, that is now 32 bit long, will eventually be stored in l.
So you might want to try something like this:

Code: Select all

unsigned long int var;
var = ((unsigned long int)FCV_TESTNO * 3192)/100000;
FCV_TESTNO = var;
Or use the pragma / compiler option.

iain wilkie
Posts: 97
Joined: Tue Jul 14, 2009 4:37 pm
Has thanked: 13 times
Been thanked: 9 times
Contact:

Re: New to C Please help !

Post by iain wilkie »

Steve,

That works !!. Being new to C I am not sure about all the pragma stuff yet, so this solution suits me, but I want to
understand it. So I understand that before the multiplication ended up as a 16 bit result and that would be causing a problem. So why does
putting the unsigned long on the variable TESTNO fix this ?

Also so I do not pester you guys all the time, is there a definitive document I can refer to on the C code. I am using Flowcode 4 for AVR ?

Regards

Iain

User avatar
Steve
Matrix Staff
Posts: 3424
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Re: New to C Please help !

Post by Steve »

This aspect of C is called "arithmetic conversion". Basically, the C compiler looks at the right side of the equation and tries to work out whether to do the calculations as ints, longs or floats, etc. By adding the "(unsigned long int)", it forces the calculation to be done using these types of numbers.

There is a BoostC.pdf manual in the "Flowcode\BoostC" directory which may help, although this specific aspect of C is not covered in detail. I think the internet is a good source of info for programming in general, so try searching for "arithmetic conversions C" or similar for the specific rules.

Post Reply