Fortran (entwickelt für wissenschaftliches Rechnen) verfügt über einen eingebauten Energieoperator. Soweit ich weiß, optimieren Fortran-Compiler das Erhöhen auf ganzzahlige Kräfte auf ähnliche Weise wie von Ihnen beschrieben. C / C ++ hat leider keinen Power Operator, nur die Bibliotheksfunktion pow()
. Dies hindert intelligente Compiler nicht daran, sie pow
speziell zu behandeln und für spezielle Fälle schneller zu berechnen, aber es scheint, dass sie dies weniger häufig tun ...
Vor einigen Jahren habe ich versucht, es einfacher zu machen, ganzzahlige Potenzen optimal zu berechnen, und habe Folgendes gefunden. Es ist C ++, nicht C, und hängt immer noch davon ab, dass der Compiler etwas klug ist, wie man Dinge optimiert / inline macht. Wie auch immer, ich hoffe, Sie finden es in der Praxis nützlich:
template<unsigned N> struct power_impl;
template<unsigned N> struct power_impl {
template<typename T>
static T calc(const T &x) {
if (N%2 == 0)
return power_impl<N/2>::calc(x*x);
else if (N%3 == 0)
return power_impl<N/3>::calc(x*x*x);
return power_impl<N-1>::calc(x)*x;
}
};
template<> struct power_impl<0> {
template<typename T>
static T calc(const T &) { return 1; }
};
template<unsigned N, typename T>
inline T power(const T &x) {
return power_impl<N>::calc(x);
}
Klarstellung für Neugierige: Dies ist kein optimaler Weg, um Kräfte zu berechnen, aber da das Finden der optimalen Lösung ein NP-vollständiges Problem ist und dies ohnehin nur für kleine Kräfte sinnvoll ist (im Gegensatz zur Verwendung pow
), gibt es keinen Grund zur Aufregung mit dem Detail.
Dann benutze es einfach als power<6>(a)
.
Dies erleichtert das Eingeben von Potenzen (es ist nicht erforderlich, 6 a
Sekunden mit Parens zu buchstabieren ) und ermöglicht Ihnen diese Art der Optimierung, ohne dass -ffast-math
Sie etwas Präzisionsabhängiges wie eine kompensierte Summierung haben (ein Beispiel, bei dem die Reihenfolge der Operationen wesentlich ist). .
Sie können wahrscheinlich auch vergessen, dass dies C ++ ist, und es einfach im C-Programm verwenden (wenn es mit einem C ++ - Compiler kompiliert wird).
Hoffe das kann nützlich sein.
BEARBEITEN:
Folgendes bekomme ich von meinem Compiler:
Für a*a*a*a*a*a
,
movapd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
Für (a*a*a)*(a*a*a)
,
movapd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm0, %xmm0
Für power<6>(a)
,
mulsd %xmm0, %xmm0
movapd %xmm0, %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1