我该如何表达呢?
How do I express this?
我正在研究如何编写以下内容:
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) ...
这表达了如何计算 4 次迭代的 x,但我如何表达它以使用可变次数的迭代?显然我可以创建一个循环并将值加在一起,但我真的很想找到一个解决这个问题的方程式。
我正在使用 C++,但我想这并不是一个特定于语言的问题(抱歉,我真的不知道还能在哪里问这个问题!)。
有什么想法吗?
谢谢,
克里斯
您可以只使用带有 for 循环的 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;
}
使用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
是幂函数。
如果循环是唯一的选择:
double x = 0;
int n = 5;
for(int exponent = 0; exponent <= n; ++exponent)
x += y*pow(z, exponent);
正如你所说,使用循环似乎是合理的。但是如果你知道编译时的迭代次数,你可以使用这样的模板:
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
可以表示为n=0到m的和。可以用一个公式表示,根据wolframalpha.
不知道这是否满足您的目的,但您可以使用递归(实际上它只是一个循环:))
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);
}
这里不需要循环,你"just"需要运用一些数学知识。
请注意,您可以将其重写为
y * (z0 + z1 + ... + zn )
现在,系列
z0 + z1 + ... + zn
总和为
(z(n+1) - 1) / (z - 1)
所以你的等式是
x = y * (z(n+1) - 1) / (z - 1)
方程求解,这是一个geometric series,因此可以用
计算
double geometric_series(double y, double z, int N) {
return y * (std::pow(z, N) - 1.0) / (z - 1.0);
}
但是使用一些 fun C++ 元编程可以获得相同的结果:如果你知道高级迭代次数并且你被允许使用 C++17 功能和fold expressions您可以按如下方式进行
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
}
我正在研究如何编写以下内容:
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) ...
这表达了如何计算 4 次迭代的 x,但我如何表达它以使用可变次数的迭代?显然我可以创建一个循环并将值加在一起,但我真的很想找到一个解决这个问题的方程式。
我正在使用 C++,但我想这并不是一个特定于语言的问题(抱歉,我真的不知道还能在哪里问这个问题!)。
有什么想法吗?
谢谢, 克里斯
您可以只使用带有 for 循环的 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;
}
使用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
是幂函数。
如果循环是唯一的选择:
double x = 0;
int n = 5;
for(int exponent = 0; exponent <= n; ++exponent)
x += y*pow(z, exponent);
正如你所说,使用循环似乎是合理的。但是如果你知道编译时的迭代次数,你可以使用这样的模板:
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
可以表示为n=0到m的和。可以用一个公式表示,根据wolframalpha.
不知道这是否满足您的目的,但您可以使用递归(实际上它只是一个循环:))
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);
}
这里不需要循环,你"just"需要运用一些数学知识。
请注意,您可以将其重写为
y * (z0 + z1 + ... + zn )
现在,系列
z0 + z1 + ... + zn
总和为
(z(n+1) - 1) / (z - 1)
所以你的等式是
x = y * (z(n+1) - 1) / (z - 1)
方程求解,这是一个geometric series,因此可以用
计算double geometric_series(double y, double z, int N) {
return y * (std::pow(z, N) - 1.0) / (z - 1.0);
}
但是使用一些 fun C++ 元编程可以获得相同的结果:如果你知道高级迭代次数并且你被允许使用 C++17 功能和fold expressions您可以按如下方式进行
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
}