| |||||
Technical Support Support Resources
Product Information | GENERAL: #DEFINES WITH ARITHMETIC DON'T WORKInformation in this article applies to:
QUESTIONI use the following #defines to create the constants I use in my program: #define AAA 1042 #define BBB (1023 * AAA) When I use BBB in my program, the result I get is around 17,000 instead of 1,065,966 which is what I expect. What is going on? Why does the compiler generate the wrong value? ANSWERThis explanation requires use of ANSI C Standard. Note that this is not a bug in the compiler. This code yields the same results in any C compiler where an int type occupies 16 bits. Here are some interesting things about the ANSI C specification as it applies to our compiler and the code above.
These three points are by ANSI specification paragraph 6.2.1.5 "Usual Arithmetic Conversions" which states the following (this is paraphrased!):
The rules are...
AND SO ON...
Remember that the result has the SAME TYPE as the operands. So, if the compiler thinks the operands are ints (16-bit), the result is an int (16-bit). Even if the result of the operation overflows! Now, we can see that 1023 * 1042 generates a value that cannot be represented in 16-bits. However, ANY C COMPILER that conforms to the ANSI standard will calculate this number as... 1042 * 1023 = 1065966 (0x001043EE) (This is a 32-bit value which is truncated into a 16-bit int.) Then, when the compiler correctly truncates this value to a 16-bit value, we get 0x43EE or 17,390 in decimal. Note that this is the value that is observed by the engineer. And this is what is specified by rule J above. The solution is to convert at least one of the operands to a long. Therefore, the result will be a long according to rule G listed above. You may convert both constants to long integers if that makes you feel more comfortable! Rule G still applies. In our example, to have the compiler implicitly cast the value of BBB to a LONG, either of the integer numeric constants (1042 or 1023) must be a long. The letter L following the number indicates (in C) that the value is a long integer type. For example, the following code generates the expected results. #define AAA 1042 #define BBB (1023L * AAA) If you run into this problem while porting existing code, the original target probably defined ints to be 32-bits. If this is the problem, you should convert all numeric constants to long ints by adding the L suffix. SEE ALSO
FORUM THREADSThe following Discussion Forum threads may provide information related to this topic. Last Reviewed: Tuesday, December 18, 2007 | ||||
| |||||