|
|||||||||||
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:
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 application of the 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...
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.
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
Last Reviewed: Thursday, February 25, 2021 | ||||||||||
|
Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.