Quote:
Originally Posted by Tom Line
My team wants to subtract 127 from each joystick to change the range from 0 to 255 to -127 to 127. We originally had trouble with this statement:
x_joy_1 = p1_x - 127; // Makes the range -127 to 127
y_joy_1 = p1_y - 127;
p1_x is a defined term from the rcdata. x_joy_1 is an int. I'm not precisely sure why we had trouble - I suspect it's because p1_x is of the wrong type (it's a define, not an int).
|
This statement would work in Visual Studio or another ISO/ANSI compliant compiler. Microchip's deviation is described in the C18 compiler user's guide:
Quote:
2.7.1 Integer Promotions
ISO mandates that all arithmetic be performed at int precision or greater. By default,
MPLAB C18 will perform arithmetic at the size of the largest operand, even if both
operands are smaller than an int. The ISO mandated behavior can be instated via the
-Oi command-line option.
For example:
Code:
unsigned char a, b;
unsigned i;
a = b = 0x80;
i = a + b; /* ISO requires that i == 0x100, but in C18 i == 0 */
Note that this divergence also applies to constant literals. The chosen type for constant
literals is the first one from the appropriate group that can represent the value of the
constant without overflow.
For example:
Code:
#define A 0x10 /* A will be considered a char unless -Oi
specified */
#define B 0x10 /* B will be considered a char unless -Oi
specified */
#define C (A) * (B)
unsigned i;
i = C; /* ISO requires that i == 0x100, but in C18 i == 0 */
|
We use -Oi because it makes things a lot easier to troubleshoot and makes the code clearer without a bunch of casts.