I have an Arduino Nano and was adding up some values `2^i from 0..7`:

``````void setup() {
Serial.begin(9600);
int i,k;
k = 0;
for (i=0;i<8;i++){
k += pow(2, i);
Serial.println(k);
}
}
``````

Those numbers should sum up to `255`, but that's the output:

``````1
3
6
13
28
59
122
249
``````

Is my Arduino not working or what can be the reason for this behaviour?

• As a tip for the future, printing the intermediate results would have given you a clue. For example, adding `Serial.print(pow(2, i), 7);` gave me: `1.0000000, 2.0000000, 3.9999995, 7.9999980, 15.9999961, 31.9999885, 63.9999771, 127.9999542`. The default output of Serial.print rounds so doing `Serial.print(pow(2, i));` masks the problem: `1.00, 2.00, 4.00, 8.00, 16.00, 32.00, 64.00, 128.00,` Commented Aug 14, 2016 at 21:12

No, there is nothing "wrong" there. In fact it's the expected results.

The problem here is that `pow()` returns a float, and some numbers just can't be represented with floating point. When that floating point value is converted to an integer it truncates the decimal portion leaving you with the wrong integer value.

``````void setup() {
Serial.begin(115200);

int t = 0;
for (int i = 0; i < 8; i++) {
float f = pow(2, i);
int d = f;
t += f;
Serial.print("2^");
Serial.print(i);
Serial.print(": float = ");
Serial.print(f, 10);
Serial.print(" int = ");
Serial.print(d);
Serial.print(" total = ");
Serial.println(t);
}
}

void loop() {
}

2^0: float = 1.0000000000 int = 1 total = 1
2^1: float = 2.0000000000 int = 2 total = 3
2^2: float = 3.9999995231 int = 3 total = 6
2^3: float = 7.9999980926 int = 7 total = 13
2^4: float = 15.9999961853 int = 15 total = 28
2^5: float = 31.9999885559 int = 31 total = 59
2^6: float = 63.9999771118 int = 63 total = 122
2^7: float = 127.9999542236 int = 127 total = 249
``````

Instead you should use bit-shifting to perform the same operation on an integer:

``````void setup() {
Serial.begin(115200);

int t = 0;
for (int i = 0; i < 8; i++) {
int d = 1 << i;
t += d;
Serial.print("1<<");
Serial.print(i);
Serial.print(": int = ");
Serial.print(d);
Serial.print(" total = ");
Serial.println(t);
}
}

void loop() {
}

1<<0: int = 1 total = 1
1<<1: int = 2 total = 3
1<<2: int = 4 total = 7
1<<3: int = 8 total = 15
1<<4: int = 16 total = 31
1<<5: int = 32 total = 63
1<<6: int = 64 total = 127
1<<7: int = 128 total = 255
``````
• Actually the values in question most definitely can be precisely represented as floats - all small integers can be, and these are even powers of two on a binary system. The issue is rather imprecision within the implementation of the pow() function, possibly having to do with intermediate values. And yes, it is not the way to do this - even apart from the inaccurate results, it is far more computationally intensive. Commented Aug 14, 2016 at 18:07
• @ChrisStratton Float is still crap either way. Q15 etc are the way forward. Commented Aug 14, 2016 at 18:09

Granted that integer arithmetic is a computationally better approach to this problem; if your intent was to learn to use floating point and float to int conversions, then you need to round up the floating result before the conversion truncates it. As you saw in @Majenko's example, the floating results are close but not quite exact. In your own example, you'd change

``````k += pow(2, i);
``````

to

``````p = pow(2, i); k += (p < 0. ? -0.5 : 0.5);
``````

to so the float would truncate to the nearest int instead to the next lower int.

• Note: that trick only works for positive numbers. For negative ones you should subtract 0.5. Or use the `round()` function. Commented Aug 14, 2016 at 19:07
• Yup, shot from the hip. Edited to show the non-`round()` version. Commented Aug 14, 2016 at 22:26