Math problem with pow()[solved]

I do not understand why pow(2,2) is given my a result of 3! What am I missing?

  int value;
   for (int i=0;i<4;i=i+1) {
      value=int(pow(2,i));
      Serial.println("Value: " +String(value));
    //};
  };
  };

Serial Log:

Value: 1 Value: 2 Value: 3 Value: 7

Did you read how it works?
https://docs.arduino.cc/language-reference/en/functions/math/pow/

Not sure if it is the solution...
int()
will return the downward rounding (truncation).
So 3.99999999999 will yield 3
And 7.99999999 will yield 7
I do not know why pow(2,2) would yield 3.999999 instead of 4.0... ...since both integers have an exact representation as binary float. This may be caused by the implementation of pow(). It can take decimals as exponent, so it will treat 2 as 2.0 and might make a small rounding error somewhere.

Haven't looked at the implementation. Perhaps it uses ln() and e^x?

1 Like

That makes sense and would explain...

OK, that all makes sense (sort off). So my mistake is the use of int variables, I didn't expect that!

Have search for a way around, worst case would be a value table.

Thanks

What are your requirements? If they're only to raise "2" to an integral power, then a left shift is the way to go.

Binary representation of floating points as fractions into sign, base, mantissa and exponent.

int base = 2, power = 16;
float result = 1;

void setup() {
  Serial.begin(115200);
  for (int i = 0; i < power; i++) { // loop "power" times
     result *= base; // recursive x = x * y
   }
  Serial.print(result, 0); // truncate decimal
}

void loop() {
}

@opus59
try the round() function

int value;   
for (int i = 0; i < 4; i = i + 1) 
{
  value = round(pow(2,i));      
  Serial.println("Value: " +String(value));    
};
   0      1
   1      2
   2      4
   3      8
   4     16
   5     32
   6     64
    for (int i = 0; i < 7; i++) { // loop "power" times
        printf (" %3d %6d\n", i, (int)( pow(2, i) +0.5));
   }
1 Like

If you spent spme time reading the Arduino language reference you would have expected it.

What is wrong with using floats?

There is no need for floats...
Just use round() to convert the resulting float to an integer...
Or write your own
int32_t intpow(int, int) function...

The function arguments are floats and the result is a double.
Why not just use the function the way it's supposed to be used.

2 Likes

If you call the func with 2 ints as arguments, they will be automatically promoted to float.
Nothing wrong with that...

@opus59

An integer only version int32_t intPower(int base, int exponent) would have some limits.

  1. if the exponent is negative, the result is (probably) zero.
  2. if the base is larger, overflow is near
  3. if the exponent is larger, overflow is near.

(finding the practical limits is left as an exercise ;)

Gives compilation error in iDE 1.8.19.

exit status 1
'intPower' was not declared in this scope

Do I need to include any library file where the function is defined?

In this thread we have seen the limits of
float pow(float, float)
...
It will not yield exact answers...
So pow(2,3)==8 will be false...

And indeed, int32_t pow( int,int) will quickly overflow...
You might add a third argument reporting error codes...
int32_t pow(int, int, &int)

+1 (good idea)

Plus we might need int64_t quite fast…

1 Like

It was left to OP to implement this not yet existing function...

1 Like