Как мне это выразить?

Я пытаюсь понять, как написать следующее:

total = (value * 0.95 ^ 0) + (value * 0.95 ^ 1) + (value * 0.95 ^ 2) ...

или же:

x = (y * z ^ 0) + (y * z ^ 1) + (y * z ^ 2) + (y * z ^ 3) ...

Это объясняет, как вычислить x для 4 итераций, но как я могу выразить это для работы с переменным числом итераций? Очевидно, я мог бы создать цикл и сложить значения вместе, но мне бы очень хотелось найти одно уравнение, которое решает это.

Я использую c ++, но я думаю, что это не проблема конкретного языка (извините, я буквально не знаю, где еще задать этот вопрос!).

Есть идеи?

Спасибо,
Крис.

4

Решение

Решение уравнений, это геометрическая серия и поэтому может быть рассчитан с

double geometric_series(double y, double z, int N) {
return y * (std::pow(z, N) - 1.0) / (z - 1.0);
}

но тот же результат может быть получен с некоторыми веселье Метапрограммирование C ++: если вы знаете число итераций в продвинутом уровне и вам разрешено использовать функции C ++ 17 и сложить выражения Вы могли бы сделать следующее

template<std::size_t... N>
double calculate_x(double y, double z, std::index_sequence<N...>) { // [0;N[
auto f = [](double y_p, double z_p, double exp) {
return y_p * std::pow(z_p, exp);
};
return (f(y, z, N) + ...);
}

template <std::size_t N>
auto calculate_x(double y, double z) {
return calculate_x(y, z, std::make_index_sequence<N>{});
}

В качестве альтернативы это также можно сделать с помощью шаблонов до C ++ 17

template <int N>
double calculate_x(double y, double z) {
return calculate_x<N-1>(y, z) + (y * std::pow(z, N - 1));
}

template <>
double calculate_x<0>(double, double) {
return 0;
}

В противном случае более простым решением было бы просто использовать цикл

double calculate_x_simple(double y, double z, int N) {
double ret = 0.0;
for (int i = 0 ; i < N ; ++i)
ret += y * std::pow(z, i);
return ret;
}

Драйвер для кода выше

int main() {

// x = (y * z ^ 0) + (y * z ^ 1) + (y * z ^ 2) + (y * z ^ 3)
double y = 42.0;
double z = 44.5;
std::cout << (calculate_x<3>(y, z) == calculate_x_simple(y, z, 3)); // 1

}
4

Другие решения

Здесь нет необходимости в цикле, вам просто нужно использовать некоторые математические вычисления.

Обратите внимание, что вы можете переписать это как

у * (г0 + Z1 + … + ZN)

Теперь серия

Z0 + Z1 + … + ZN

суммы в

(П + 1) — 1) / (z — 1)

так что ваше уравнение будет

х = у * (г(П + 1) — 1) / (z — 1)

9

Как вы упомянули, кажется разумным использовать цикл. Но если вы знаете количество итераций во время компиляции, вы можете использовать такие шаблоны:

template <int n>
double foo(double y, double z)
{
return foo<n-1>(y, z) + y * std::pow(z, n);
}

template <>
double foo<-1>(double, double)
{
return 0;
}

С небольшой оптимизацией это развернется к одно уравнение.

Пример:

#include <iostream>
#include <cmath>

template <int n>
double foo(double y, double z)
{
return foo<n-1>(y, z) + y * std::pow(z, n);
}

template <>
double foo<-1>(double, double)
{
return 0;
}int main()
{
std::cout << foo<2>(2,3) << std::endl;
}

Выход: 26

3

Если цикл будет единственным вариантом:

double x = 0;
int n = 5;
for(int exponent = 0; exponent <= n; ++exponent)
x += y*pow(z, exponent);
3

Вы можете просто использовать math.pow функция с циклом

#include <stdio.h>
#include <math.h>

int main(void) {
int i;
int n = 5;
double y = 0.5;
double z = 0.3;
double answer = 0;
for (i = 0  ; i < n ; i++)
answer += y * pow(z,i);

printf("%f", answer);
return 0;
}
2

Это может быть выражено как сумма от n = 0 до m. Это может быть выражено в одной формуле, в соответствии с вольфрам Альфа.

2

Не знаю, соответствует ли это вашей цели, но вы можете использовать рекурсию (которая в реальном выражении является только циклом :))

int x = evaluate(y, z, count);int evaluate(y,z, count)
{
if (count <= 0)
return 0;

return (evaluate(y, z, count-1) + y*z^count);
}
2

С помощью n как количество итераций,

#include <cmath>
double foo(double y, double z, int n)
{
double x =0;
for(int i = 0 ; i<n; ++i){
x+=y*std::pow(z,i);
}
return x;
}

куда std::pow является степенной функцией.

2
По вопросам рекламы [email protected]