44 lines
1.1 KiB
C++
44 lines
1.1 KiB
C++
#pragma once
|
|
|
|
#include <cmath>
|
|
|
|
#include "rational.h"
|
|
|
|
// Возведение в степень для целочисленных показателей
|
|
template<class Number>
|
|
Number IntegerPow(Number l_op, Number r_op) {
|
|
Number res = 1;
|
|
while (r_op > 0) {
|
|
if (r_op & 1) {
|
|
res *= l_op;
|
|
}
|
|
r_op >>= 1;
|
|
l_op *= l_op;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// Возведение в степень для всех типов кроме Rational
|
|
template<class Number>
|
|
Number Pow(Number lhs, Number rhs) {
|
|
if constexpr (std::is_floating_point_v<Number>) {
|
|
return static_cast<Number>(std::pow(lhs, rhs));
|
|
} else {
|
|
return IntegerPow(lhs, rhs);
|
|
}
|
|
}
|
|
|
|
// Возведение в степень для типа Rational
|
|
inline Rational Pow(Rational lhs, Rational rhs) {
|
|
if (rhs.GetDenominator() != 1) {
|
|
std::abort();
|
|
}
|
|
|
|
const auto pow = rhs.GetNumerator();
|
|
if (pow >= 0) {
|
|
return {IntegerPow(lhs.GetNumerator(), pow), IntegerPow(lhs.GetDenominator(), pow)};
|
|
}
|
|
|
|
return {IntegerPow(lhs.GetDenominator(), -pow), IntegerPow(lhs.GetNumerator(), -pow)};
|
|
}
|