Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: pow() function alternative

  1. #1

    pow() function alternative

    Hi, i have had trouble with the pow() function not having the precision I need (floats).
    I wrote a small library to replace the pow() but wonder about the for-loop, will that slow things down?

    /Johan

    <CODE>
    #ifndef NucleusPow_h
    #define NucleusPow_h
    #include "Arduino.h"
    class NucleusPow{
    public:
    NucleusPow();
    float pow(float base, int exponent);
    private:
    float _base;
    };
    #endif
    </CODE>

    <CODE>
    #include "NucleusPow.h"
    NucleusPow::NucleusPow(){}
    float NucleusPowow(float base, int exponent){
    _base=base;
    for(int _loop=1;_loop<exponent;_loop++){
    _base*=base;
    }
    return _base;
    }
    </CODE>
    Last edited by johanbilen; 11-21-2020 at 07:10 PM. Reason: Code change

  2. #2
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    7,529
    Hm, what exactly is wrong with pow() ?

    note, pow() is the double-precision version. you need to include <math.h>
    powf() is the float version.

    pow(PI, PI) prints as 36.462159607207901 which is pretty exact.

  3. #3
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    811
    > will that slow things down

    If you are concerned about speed, then I encourage you to learn how to measure speed. Search this forum for "ARM_DWT_CYCCNT".

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,132
    Quote Originally Posted by Frank B View Post
    Hm, what exactly is wrong with pow() ?

    note, pow() is the double-precision version. you need to include <math.h>
    powf() is the float version.

    pow(PI, PI) prints as 36.462159607207901 which is pretty exact.
    Indeed it is - Windows gives this for pi^pi :: 36.462159607207911770990826022692

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    7,529
    Quote Originally Posted by johanbilen View Post
    Frank B, I will have a look at powf(). I did pow(1.5,3) and got something like 3.08 instead of 3.375 when printing it through Serial.print().

    /Johan
    Print rounds if you don't display more digits.

    try Serial.print( pow(a,b), 20)
    (that's double)
    powf() is not good as pow() but you wanted float ..

  6. #6
    Frank B, yes just discovered that Serial.print() round things off. So I'll guess I can go back to using pow() then :-)
    Thanks
    Johan

  7. #7
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,921
    You didn't mention what microprocessor you are using. And for floats, use powf, not pow, because powf takes float arguments, does most of the calculations in float and returns float arguments. While pow takes double arguments, does the calculates in double, and returns double.

    • On the Teensy LC, 3.0, 3.1, and 3.2, both float and double are emulated in software;
    • On the Teensy 3.5, and 3.6, float is done in hardware, and double is emulated in software; (and)
    • On the Teensy 4.0, and 4.1, both float and double are done in hardware.


    Even if you use the Teensy 4.0/4.1, if you only need float results, you should use powf, because pow likely has more passes to provide the higher precision in double.

  8. #8
    Don't bother with the powf and pow C functions, use the C++ function std::pow from the <cmath> header, it'll always select the right version: double if the arguments are doubles, float if the arguments are floats.

    Pieter

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •