Faustregel, wann std::pow am effizientesten ist?


  • Mod

    Moment mal. Wenn die Zahl der Multiplikationen zur Compile-Zeit feststeht... wisst ihr, wovon ich spreche? 🤡



  • Arcoth schrieb:

    Moment mal. Wenn die Zahl der Multiplikationen zur Compile-Zeit feststeht... wisst ihr, wovon ich spreche?

    Ja, boost::pow.



  • Vorschlag (aber nur für positive Exponenten):

    namespace detail {
    
    	template <typename T, unsigned N>
    	struct pow {
    		static T value(T x) {
    			T s = pow<T, (N >> 1)>::value(x); // teile und herrsche!
    			return s * s * (1 + (N & 1) * (x - 1)); // = s^2 * s, falls N ungerade, sonst s^2 
    		}
    	};
    
    	template <typename T>
    	struct pow<T, 1> {
    		static T value(T x) {
    			return x;
    		}
    	};
    
    	template <typename T>
    	struct pow<T, 0> {
    		static T value(T x) {
    			return x;
    		}
    	};
    }
    
    template <unsigned N, typename T>
    T static_pow(T base) {
    	return detail::pow<T, N>::value(base);
    }
    
    ...
    
    static_pow<6>(3.14159);
    


  • Hoppla, bei der Spezialisierung soll natürlich 1 und nicht x stehen.



  • Also der Spezialisierung von 0.



  • Arcoth schrieb:

    Moment mal. Wenn die Zahl der Multiplikationen zur Compile-Zeit feststeht... wisst ihr, wovon ich spreche? 🤡

    Kann ich davon ausgehen, dass der compiler ein "std::pow(d, i)", wobei "i" eine Compiletime Konstante ist, in die optimale Form übersetzt? Also gilt zB. das hier?

    double d = a*a;            // sind die beiden Ausdrücke gleichwertig,
    double d = std::pow(a, 2); // weil der Optimierer hier a*a raus macht?
    

    Irgendwie kann ich nie einschätzen, wie klug der Compiler ist 😃



  • Exponents schrieb:

    Kann ich davon ausgehen, dass der compiler ein "std::pow(d, i)", wobei "i" eine Compiletime Konstante ist, in die optimale Form übersetzt? Also gilt zB. das hier?

    double d = a*a;            // sind die beiden Ausdrücke gleichwertig,
    double d = std::pow(a, 2); // weil der Optimierer hier a*a raus macht?
    

    Kommt auf den Compiler drauf an:

    Irgendwie kann ich nie einschätzen, wie klug der Compiler ist 😃

    Kommt auf den Compiler drauf an. GCC und Clang inlinen pow(a,2) zu a*a, aber pow(a,3) schon nicht mehr. Der icc inlined bis zu pow(a,200), aber pow(a,201) nicht mehr.



  • OhneBooooooost schrieb:

    template <typename T>
    	struct pow<T, 0> {
    		static T value(T x) {
    			return x;
    		}
    	};
    

    Weil [c]x^0[/c] bekanntermaßen [c]x[/c] ist... x^0 ist nicht x .
    Außerdem fehlt da constexpr .

    EDIT: Oh, bin auch noch zu spät mit der 1.



  • TyRoXx schrieb:

    Weil x^0 bekanntermaßen x ist...

    x^0=1



  • daddy_felix schrieb:

    TyRoXx schrieb:

    Weil x^0 bekanntermaßen x ist...

    x^0=1

    Nein, x^0 = x XOR 0 = x



  • TyRoXx schrieb:

    OhneBooooooost schrieb:

    template <typename T>
    	struct pow<T, 0> {
    		static T value(T x) {
    			return x;
    		}
    	};
    

    Weil [c]x^0[/c] bekanntermaßen [c]x[/c] ist... x^0 ist nicht x .
    Außerdem fehlt da constexpr .

    EDIT: Oh, bin auch noch zu spät mit der 1.

    Wo soll da ein constexpr hin? Die Basis ist ein Laufzeitwert.


Anmelden zum Antworten