You have answered most of your question in your comment.
Your problem is similar to the surprise some programmers have with float f = 5 / 3;
that the division is computed as an integer division, although it is destined to be assigned to a float
. The solution in their case is to use float f = 5.0 / 3.0;
instead.
If the expressions being divided or, in your case, multiplied, are not constants, you can convert them to a wider type with a cast: float f = (float)int_var1 / (float)int_var2;
or, in your case, unsigned long foo = (unsigned long)int_var1 * (unsigned long)int_var2;
. You could also convert to double
so that the computed multiplication is a double
multiplication: accelSum = (double)int_var1 * (double)int_var2;
.
Only one of the casts is actually necessary because of “promotion rules”, but it is just as clear to write both.
If you are interested in the details, the C standard mandates that the type of an integer constant is selected as the first type that can represent the constant in a list. In C99(*), the list is int
, long
, long long
. In your case, a 16-bit int
is enough to contain 10000
or 200
, so int
is picked as the type of these constants.
(*) The idea was the same but the list was different in C90.