 # Not able to cast pow() to a byte or int :(

Hi!
Im trying to make powers of two (2^x), but the result given is not what i would expect Anyone can try this code and look at the serial monitor to get the results

``````void setup() {
byte tempB;
int tempI;
double tempD;
float tempF;

Serial.begin(115200);

for(byte x = 0; x < 8; x++){
tempB = pow(2, x);
tempI = pow(2, x);
tempD = pow(2, x);
tempF = pow(2, x);

Serial.print("Base 2, Exp ");
Serial.print(x);

Serial.print(" = B:");
Serial.print(tempB);

Serial.print(" I:");
Serial.print(tempI);

Serial.print(" D:");
Serial.print(tempD);

Serial.print(" F:");
Serial.println(tempF);
}
}
``````

For this code, i get this output:

``````Base 2, Exp 0 = B:1 I:1 D:1.00 F:1.00
Base 2, Exp 1 = B:2 I:2 D:2.00 F:2.00
Base 2, Exp 2 = B:3 I:3 D:4.00 F:4.00
Base 2, Exp 3 = B:7 I:7 D:8.00 F:8.00
Base 2, Exp 4 = B:15 I:15 D:16.00 F:16.00
Base 2, Exp 5 = B:31 I:31 D:32.00 F:32.00
Base 2, Exp 6 = B:63 I:63 D:64.00 F:64.00
Base 2, Exp 7 = B:127 I:127 D:128.00 F:128.00
``````

As you can see, for exponent 2 and up, the result of the pow() is one unit less than expected when this result is stored on a byte or an int.

I guess the problem is that the result given by pow() is an approximation, something like:
pow(2, 3) = 2^3 = 7.9999

So, when casting down, the decimal points are lost.

Ive tried to find out what was happening on the root:
http://svn.savannah.gnu.org/viewvc/avr-libc/branches/avr-libc-1_6-branch/avr-libc/libm/fplib/pow.S?revision=1533&view=markup

But my ASM skills are quite rusty Any suggestion?

For powers of two, the pow() function is the worst possible choice, as it uses floating point arithmetic, with logarithms and exponentials, and suffers from rounding problems.

The shift operator works for integers

2^N = 1<<N

Thanks for that quick answer! Just checked that if i show more decimal places for the result, then i see that in fact there are not round numbers:

``````Base 2, Exp 0 = B:1 I:1 D:1.000000000 F:1.000000000
Base 2, Exp 1 = B:2 I:2 D:2.000000000 F:2.000000000
Base 2, Exp 2 = B:3 I:3 D:3.999999523 F:3.999999523
Base 2, Exp 3 = B:7 I:7 D:7.999998092 F:7.999998092
Base 2, Exp 4 = B:15 I:15 D:15.999996185 F:15.999996185
Base 2, Exp 5 = B:31 I:31 D:31.999988555 F:31.999988555
Base 2, Exp 6 = B:63 I:63 D:63.999977111 F:63.999977111
Base 2, Exp 7 = B:127 I:127 D:127.999954223 F:127.999954223
``````

So strange, as the powers of 2 are the most "simple" to calculate...

So strange, as the powers of 2 are the most "simple" to calculate...

The pow() function is not simple, but does not make choices for you.

Marttyn: So strange, as the powers of 2 are the most "simple" to calculate...

For you on paper with your organic brain capable of handling abstract concepts. But for a machine math is done a little differently. Powers is kind of hard for a machine to do.

jremington:
The pow() function is not simple, but does not make choices for you.

Delta_G:
For you on paper with your organic brain capable of handling abstract concepts. But for a machine math is done a little differently. Powers is kind of hard for a machine to do.

I meant that powers of 2 are the simplest for the uC, as its straight forward binary shifting, you can do

2^N = 1<<N

As jremington mentioned. Not that simple for any other number… well, except for 0 and 1 pow() takes floats as arguments, so you have to think in terms of floats.

Bit shifting floats takes you into much murkier territory.

GypsumFantastic: pow() takes floats as arguments, so you have to think in terms of floats.

Bit shifting floats takes you into much murkier territory.

There is nothing at all murky about. Bit-shifting floats is completely meaningless... Regards, Ray L.

Marttyn:
I meant that powers of 2 are the simplest for the uC, as its straight forward binary shifting, you can do

2^N = 1<<N

So, if you know this, why are you trying to use pow()?

gfvalvo: So, if you know this, why are you trying to use pow()?

I was trying to make code more readable. Bit shifting is more geeky, harder to understand for someone thats not a programmer.

If the code is supposed to be readable by people who don’t know how to program, does it help to write 222*2 for 24?

Delta_G: For you on paper with your organic brain capable of handling abstract concepts. But for a machine math is done a little differently. Powers is kind of hard for a machine to do.

But the machine itself has been built by the 'organic brain'; if so, why has he (the organic brain') shown inability in implanting within the machine a little bit of the intellect that he possesses? Are man (the organic brain) and machine are different entities?

GolamMostafa: But the machine itself has been built by the 'organic brain'; if so, why he (the organic brain') has shown inability in implanting within the machine a little bit of the intellect that he possesses! Are man (the organic brain) and machine are different entities?

Yes.

jremington:
If the code is supposed to be readable by people who don’t know how to program, does it help to write 222*2 for 24?

That notation doesn’t help to represent 20. 8)

jremington:
If the code is supposed to be readable by people who don’t know how to program, does it help to write 222*2 for 24?

AWOL:
That notation doesn’t help to represent 20. 8)

None of them is a concept; 20 = 1 is a definition, and 222*2 = 24 is a mathematical formulation.

Marttyn: Bit shifting is more geeky, harder to understand for someone thats not a programmer.

Why do you care what non-programmer things about your code? Why would a non-programmer be looking at your code?

Marttyn: I was trying to make code more readable. Bit shifting is more geeky, harder to understand for someone thats not a programmer.

Allow me to introduce you to...