Power (pow) returns incorrect result

Any bugs you encounter with Flowcode should be discussed here.
Post Reply
mnfisher
Valued Contributor
Posts: 2105
http://meble-kuchenne.info.pl
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 165 times
Been thanked: 967 times

Power (pow) returns incorrect result

Post by mnfisher »

Just spent a while chasing a bug in my code - but it turns out 'pow' returns an incorrect value.

It actually returns the result - 1 (except for pow(2, 0) and pow(2, 1))

The attached demonstrates this behaviour (on an Arduino - other devices may differ?):
2**0 = 1
2**1 = 2
2**2 = 3
2**3 = 7
2**4 = 15
2**5 = 31
2**6 = 63
2**7 = 127
2**8 = 255 // The example in the WIKI should = 256!
Martin
Attachments
pow_test.fcfx
(10.18 KiB) Downloaded 28 times

mnfisher
Valued Contributor
Posts: 2105
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 165 times
Been thanked: 967 times

Re: Power (pow) returns incorrect result

Post by mnfisher »

It might be because it uses floating point...

pow(2, flt_fromi(FCL_I));

- not sure why it doesn't also do flt_fromi(2)?

However - it shouldn't make it so wrong ?

Wrote my own integer

Steve-Matrix
Matrix Staff
Posts: 1985
Joined: Sat Dec 05, 2020 10:32 am
Has thanked: 296 times
Been thanked: 459 times

Re: Power (pow) returns incorrect result

Post by Steve-Matrix »

Thanks, Martin.

I've just checked and confirmed this. But on an 8-bit PIC it's fine.

If I strip out the flt_* functions in C code, then there are some oddities:

Code: Select all

FCV_F = pow(2, 4);   //this produces 16.00000

//but...

FCV_I = 4;
FCV_F = pow(2, FCV_I);   //this produces 15.999999

FCV_I = pow(2, FCV_I);   //this produces 15
(FCV_F is a float and FCV_I is an int).

So there is a truncation issue.

Perhaps the "pow" function in the Arduino is using some algorithm that makes the power calculation quicker, but introduces this truncation issue.

We'll continue to investigate.

mnfisher
Valued Contributor
Posts: 2105
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 165 times
Been thanked: 967 times

Re: Power (pow) returns incorrect result

Post by mnfisher »

This might give a solution:

Code: Select all

#include <math.h>
#include <stdio.h>

int main()
{
    int a, b;

    // Using typecasting for
    // integer result
    a = (int)(pow(5, 2) + 1e-9);
    b = round(pow(5,2));
    printf("%d \n%d", a, b);

    return 0;
}

Which looks to give the correct result on both cases (from stackoverflow)

Steve-Matrix
Matrix Staff
Posts: 1985
Joined: Sat Dec 05, 2020 10:32 am
Has thanked: 296 times
Been thanked: 459 times

Re: Power (pow) returns incorrect result

Post by Steve-Matrix »

More on this. It's not a bug as such. It's the way the pow() function works in the C code for Arduino/AVR.

The pow() function returns a float. And if a float is casted to an int then this is a truncation rather than a rounding. So 15.999999 becomes 15 and not 16.

So in your code it's probably wise to use the round() function if you are definitely expecting an integer rather than relying on C casting.

Code: Select all

myInt = round( pow(2, x) )

Post Reply