# Unexpected negative values from abs() function inline with analogRead

When sampling from A0 with a 0-5V signal on an arduino micro with the code below I get some negative values.

``````int sensor = 0;
sensor = abs(analogRead(A0) - 512);
``````

Values:

``````77
25
-74
-58
46
113
-74
102
-91
-51
-126
47
31
``````

When running the (apparently) mathematically equivalent code below I get exclusively positive values.

``````int sensor = 0;
sensor = sensor - 512;
sensor = abs(sensor);
``````

I don't think this is an integer overflow as in this post because when I switch to `long sensor = 0` I get the same negative results.

What's going on here?

`abs()` is defined in Arduino.h as a macro:

`````` #define abs(x) ((x)>0?(x):-(x))
``````

A macro does not evaluate in the same way as a function.

`````` sensor = abs(analogRead(A0) - 512);
``````

This statement will be expanded at compile-time to:

`````` sensor = ((analogRead(A0) - 512)>0?(analogRead(A0) - 512):-(analogRead(A0) - 512));
``````

Now the "error" is easy to understand. The analog pin is read twice. The "error" can be avoided by adding the following line first in your sketch:

``````#undef abs
``````

This will remove the macro `abs()` and the standard library function will be used instead.

Cheers!

• The error is the `abs()` macro in Arduino.h
– Jot
Mar 14, 2019 at 6:33
• Thanks for the clear answer. I had no idea that macros even existed in the Arduino world. I found a post from 2011 discussing this and a short list of other macros. Do you know of a definitive list? Is it just more "Arduinoesque" and better practice to avoid multiple assignments in a line and stick to one operation per line? Mar 14, 2019 at 7:05
• No, it is not more Arduinoesque to use only one operation in one assignment. Sometimes this is done to make it easier to read. Your problem with macros does not have to do much with Arduino. It is more generally about how macros are evaluated by the compiler. The compiler replaces the macro with what is written in it's definition (and puts in the argument). It is not a function. And this is not Arduino specific, but depends on the compiler. You can also use macros, when programming with other compilers. Macros can be useful, but you have to use them with caution. Mar 14, 2019 at 8:18
• @chrisl, there is already a `abs` and `labs` function. The arduino `abs` macro is a ludicrous blunder by arduino. Aaron Ciuffo, click on the link to Arduino.h in the answer by Mikael Patel, there you see the other macros. Another thing is not to use a variable with the name "B1".
– Jot
Mar 14, 2019 at 8:23