View Single Post
  #2   Spotlight this post!  
Unread 13-01-2008, 14:50
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,586
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: Multiplication in EasyC returns insane values!

Quote:
Originally Posted by Nathan View Post
That's what I thought I did at first, but I already had it as an INT. I tried doing the math operations using DOUBLEs as well, but no difference...

Still stuck here,
Nathan
This statement would work in Visual Studio or another ISO/ANSI compliant compiler. The Microchip C18 compiler (which easy C uses at the back end) is not ANSI compliant. The particular deviation you are running into 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 */
This explains the problem with your first example because even though you put the final value as an integer, C18 calculates the result as an 8 bit value, since both operands are 8 bit values. One way to fix this is to cast one of the operands as an int, or to use the -Oi compiler option

I don't use easyC, so I don't know if it possible to cast or change compiler options, but hopefully that gives you an idea where to look.

For the second example, use an unsigned int (if unsigned is OK) or long if you need to maintain signs, since you are overflowing a signed int.