# Arduino: incorrect calculation of long integer

I'm doing a simple calculation with integers (on Arduino with ESP8266 12E), but I can't get the expected result and can't find the error. Can someone guide me?

``````#define A      200
#define B      A * 62
#define C      500

void setup() {
Serial.begin(9600);
Serial.println("");

unsigned long aux = 0;

aux = (B * 500) / C;    // (12400 * 500) / 500 = 12400
Serial.printf("aux = %d\n", aux);
aux = aux * C;          // 12400 * 500 = 6200000
Serial.printf("aux = %d\n", aux);

// ERROR: Should result in "500", but is resulting in "1922000"
aux = aux / B;          // 6200000 / 12400 = 500

Serial.printf("aux = %d\n", aux); // It's printing "1922000"
}
``````

## 3 Answers

In your #define of B you missed parenthesis (). Change your definition to:

``````#define B      (A * 62)
``````

Without parenthesis you first divide 6200000 by 200 and then multiply result by 62, which is not what you intend.

• Dude, you're 100% right. I've spent several hours trying to figure out what was wrong ... Thank you so much!
– wBB
Dec 28, 2018 at 14:44
• @wBB remember that in C, macros are replaced in the code, exactly as you wrote them, in the preprocessor step before the code gets compiled. So it helps as a sanity-check in these cases to expand the macros yourself in your code to see if you're getting what you intended. Dec 28, 2018 at 15:19
• It really is was my lack of exeperience in C that led me to the problem. Thanks!
– wBB
Dec 28, 2018 at 18:18

Fully-parenthesizing macros (as noted in answer by dmz) solves one class of problem.

Another thing you should do is, in any arithmetic expression which involves literal constants, use the `L` suffix on at least one of the constants involved if there's any chance the result will exceed 32767 (the maximum guaranteed-representable value for `int`). The type of an arithmetic operation in C is based on the types of the operands of that operation only; the type of the variable to which the result is assigned is irrelevant.

(edit) For example:

``````long q, r;
unsigned char v = 231;
unsigned char w = 197;

q = v * w * 5;
r = v * w * 5L;
``````

`q` might contain 30927, since after the Usual Arithmetic Conversions (6.3.1.8) [in this case, the Integer Promotions (6.3.1.1-2)] all operands are of type `int` and it's possible for `INT_MAX` to be 32767 in which case each operation would be performed modulo 32768.

`r` will contain 227535, since the constant `5L` is of type `long` and thus all operations in this expression will be performed on values of type `long`.

• ...and the format specifier for an `unsigned long` is `%lu` not `%d` - the compiler for the asker's esp8266 uses a 32-bit `int` so they get away with some things they would not on an ATmega-based Arduino where an `int` is the minimum 16 bit size allowed by the specification. Dec 28, 2018 at 16:27
• @mlp usually I use a typecast on almost everything. Example: `int J = -1`, typecast `(unsigned char) J //prints 255`. When you talk about the suffix `L`, what do you mean? Can you give an example?
– wBB
Dec 28, 2018 at 18:33

As explained in previous answers, fully parenthesizing the macros is the standard solution to this problem in C. However, on Arduino you are programming in C++, and in C++ it is considered good practice to replace this usage of `#define` by explicit constants:

``````const int A = 200;
const int B = A * 62;
const int C = 500;
``````

Not only this makes the initial problem go away, it also provides some type safety: you can choose to give these constants other types (e.g. `long`) if appropriate.

• Some compilers will interpret "const" as a variable going into program memory which then in turn results in issues with memory spaces. Consts offer type protection, which can also be (partially) achieved by casting inside the define "#define A ((int)200)" for instance. Dec 30, 2018 at 0:08
• @le_top: Do you have a specific example of the kind of “issues with memory spaces” you can get? I doubt you could find an example that does not invoke undefined behavior. Dec 30, 2018 at 10:08
• Something along these lines for example: "const int a=100; int b=200; void setB(const int *c) {b=c;} void ex1() {setB(&a);}" . But there are other cases. When "const" puts "a" in ROM, some embedded compilers can not cope with this kind of assignment and do not report all violating cases. So I tend to put "CONST" if there is a future risk for this. (with a "#define CONST const" if possible). Dec 30, 2018 at 18:23
• @le_top: I guess you mean `b=*c`. This sounds like a compiler bug to me. What compiler had issues with this? I tried your code on avr-gcc, and it had no issues, even when I replaced `const` by `__flash const`, which has the effect of putting `a` in flash. Dec 30, 2018 at 20:35
• Yes, b=*c. It will depend on the compiler and the uC. I file reports when I find bugs - when the compiler does not warn about it it is a bug, but otherwise it is a documented limitation.On Arduino you should use PROGMEM rather than __flash. I do not want to put a specific compilrer forward, my comment was mainly about warning that there are compilers for embedded systems that interpret const in a way that breaks code compatibility. That's also why you're required to add "__flash" to get the variable in FLASH - keeping it in RAM eases code generation (and speed) for those processors. Dec 31, 2018 at 11:19