Here's a little thingie to make you wonder (at least it made me wonder a lot!).
Check out this simple bit of code:
void setup() {
Serial.begin(9600);
byte i;
int bla;
for (i=0; i<4; ++i) {
bla = pow(2,i);
Serial.println(bla);
}
}
void loop() {
}
Run it... i'm curious what results you will get. On my Arduino (Diecimila) I get this:
1
1
3
7
Where I would expect:
1
2
4
8
??????
If I change the basenumber ("2" in the example) to 3 or 4.... the results make sense!
(1,3,9,27) resp (1,4,16,64)
What am I doing wrong????
BTW, what I'm trying to accomplish is this: I have 4 buttons in a row, and I want to my function to return the decimal number that corresponds with the binary number that would be formed by the pressed and unpressed buttons, like this:
(some parts borrowed from examples on this site)
/*
* RobotKit - v0.2
*/
#define DEBOUNCE 20
void setup() {
byte i;
// set up serial port
Serial.begin(115200);
// set up pins communicating with switches as input
for (byte i = 2; i <= 5; ++i) {
pinMode(i, INPUT);
}
}
void loop() {
static byte previous[8];
static long time[8];
byte reading;
byte index;
int selected = 0;
for (index = 0; index < 4; ++index) {
reading = digitalRead(index + 2);
if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
{
// switch pressed
time[index] = millis();
selected += pow(2, index);
}
previous[index] = reading;
}
Serial.print("result = ");
Serial.println(selected);
delay(500);
}
Is it a bug?? I see a few examples on this forum which are using the pow function, also with basenumber 2, and they seem to cause zero problems.
Help! Please! :-/
The problem with your code example stems from the fact that pow is a floating-point function, and floating-point arithmetic is never completely accurate. My guess is that pow(2, 2) is returning something like 3.999997. Because C++ converts double to int by simply truncating, when you assign the result of pow to your int variable bla, you get the surprising result of 3 instead of 4.
But as you discovered, if you are simply tracking the state of 4 buttons, it is much easier, not to mention more efficient and accurate, to use bits within a byte and avoid the expensive call to pow altogether.
Aha, that surely sheds some light on the matter. Thanks for your explanation. Still it leaves me wondering though, because: if I replace the reference to index by a hardcoded number (i.e. 2 or 3), without changing any other part of the code, the result is what it should be (resp. 4 and 8), even though the same truncating would occur...?
Anyway, I've been able to solve this whole issue with the approach mentioned above, using the SET(x,y) function.
Now all I have to do is wait for my WaveShield to arrive..... exciting! :o
The compiler tries to recognize calculations on constants at compile time and substitute the constant results ( resp. 4 and 8 in your example ) and not bother to call the floating point function, so it s not truncated.
EDIT: cut out a whole description of the same problem, the search engine had only given methe first post, not the explenation as to why it happens. Thanks for the feedback, now i can solve my problem as well.