Faustregel, wann std::pow am effizientesten ist?
-
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 nichtx
.
Außerdem fehlt daconstexpr
.EDIT: Oh, bin auch noch zu spät mit der 1.
-
TyRoXx schrieb:
Weil
x^0
bekanntermaßenx
ist...x^0=1
-
daddy_felix schrieb:
TyRoXx schrieb:
Weil
x^0
bekanntermaßenx
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 nichtx
.
Außerdem fehlt daconstexpr
.EDIT: Oh, bin auch noch zu spät mit der 1.
Wo soll da ein constexpr hin? Die Basis ist ein Laufzeitwert.