一个序列的总和
The sum of a sequence
我正在尝试创建一个函数来计算这个公式
#include <iostream>
#include <vector>
double Sequence(std::vector < double > & a) {
double result = 0;
for (int i = a.size() - 1; i > 0; i--) {
if (a[i] == 0) throw std::domain_error("Dividing with 0");
if (i > 1)
result += 1 / (a[i - 1] + 1 / a[i]);
else result += a[i - i];
std::cout << a[i] << " " << result << " " << "\n";
}
return result;
}
int main() {
std::vector<double>a{1,2,3,4,5};
try {
std::cout << Sequence(a);
} catch (std::domain_error e) {
std::cout << e.what();
}
return 0;
}
代码给出了 {1,2,3} 序列的正确结果。但是,如果我在该序列中添加一些数字,结果就会出错。你能帮我解决这个问题吗?
if (i > 1)
result += 1 / (a[i - 1] + 1 / a[i]);
else result += a[i - i];
这是错误的;如果你有三个或更少的任期,它恰好有效。
您真正想要的重复是
if (i == a.size() - 1) {
result = a[i];
} else {
result = a[i] + 1 / result;
}
你可以看到这是一个正确的循环,因为
整理更多东西(从循环内部删除条件,修复循环终止条件中的 off-by-one,并更正异常条件):
double Sequence(std::vector<double> &a) {
double result = a[a.size() - 1];
for (int i = a.size() - 1; i >= 0; i--) {
if (result == 0)
throw std::domain_error("Dividing with 0");
result = a[i] + 1 / result;
}
return result;
}
这称为简单连分数,其中所有分子均为 1。它基本上表示为 [a1;a2,a3,...,an]
(实际上是从 a0
开始,但无论如何)。您可以从上到下计算结果,同时在每一步获得更好的近似值(或他们所说的 convergent)。
这个有限有理级数或无限无理级数的结果表示为p/q
。为了计算你假设的结果
p0 1 p1 a1 p2 a2*p1+p0 p3 a3*p2+p1 pn a_n*p_n-1+p_n-2
__ = _ and __ = __ then __ = ________ then __ = ________ .. then .. __ = _______________
q0 0 q1 1 q2 a2*q1+q0 q3 a3*q2+q1 qn a_n*q_n-1+q_n-2
并且每个下一个 p_x/q_x
都会产生更好的结果近似值。
比如说,如果你在连续分数效率中得到一个像 1.425
这样的小数 as
[1; 2, 2, 1, 5]
a.k.a.
1
1 + _____________
1
2 + _________
1
2 + _____
1
1 + _
5
那么如上所述计算出的中间收敛点为;
1 1 3 7 10 57
_ -> _ -> _ -> _ -> __ -> __ = 1.425
0 1 2 5 7 40
请注意,除了 57/40
是 1.425
.
的最小有理表达式之外,每个收敛的超调随后都会从最终结果上下移动
连分数是一个非常深奥的话题,一旦以连分数形式在它们之间建立算术,实际上就消除了浮点错误。
可以玩here.
我正在尝试创建一个函数来计算这个公式
#include <iostream>
#include <vector>
double Sequence(std::vector < double > & a) {
double result = 0;
for (int i = a.size() - 1; i > 0; i--) {
if (a[i] == 0) throw std::domain_error("Dividing with 0");
if (i > 1)
result += 1 / (a[i - 1] + 1 / a[i]);
else result += a[i - i];
std::cout << a[i] << " " << result << " " << "\n";
}
return result;
}
int main() {
std::vector<double>a{1,2,3,4,5};
try {
std::cout << Sequence(a);
} catch (std::domain_error e) {
std::cout << e.what();
}
return 0;
}
代码给出了 {1,2,3} 序列的正确结果。但是,如果我在该序列中添加一些数字,结果就会出错。你能帮我解决这个问题吗?
if (i > 1)
result += 1 / (a[i - 1] + 1 / a[i]);
else result += a[i - i];
这是错误的;如果你有三个或更少的任期,它恰好有效。
您真正想要的重复是
if (i == a.size() - 1) {
result = a[i];
} else {
result = a[i] + 1 / result;
}
你可以看到这是一个正确的循环,因为 整理更多东西(从循环内部删除条件,修复循环终止条件中的 off-by-one,并更正异常条件):
double Sequence(std::vector<double> &a) {
double result = a[a.size() - 1];
for (int i = a.size() - 1; i >= 0; i--) {
if (result == 0)
throw std::domain_error("Dividing with 0");
result = a[i] + 1 / result;
}
return result;
}
这称为简单连分数,其中所有分子均为 1。它基本上表示为 [a1;a2,a3,...,an]
(实际上是从 a0
开始,但无论如何)。您可以从上到下计算结果,同时在每一步获得更好的近似值(或他们所说的 convergent)。
这个有限有理级数或无限无理级数的结果表示为p/q
。为了计算你假设的结果
p0 1 p1 a1 p2 a2*p1+p0 p3 a3*p2+p1 pn a_n*p_n-1+p_n-2
__ = _ and __ = __ then __ = ________ then __ = ________ .. then .. __ = _______________
q0 0 q1 1 q2 a2*q1+q0 q3 a3*q2+q1 qn a_n*q_n-1+q_n-2
并且每个下一个 p_x/q_x
都会产生更好的结果近似值。
比如说,如果你在连续分数效率中得到一个像 1.425
这样的小数 as
[1; 2, 2, 1, 5]
a.k.a.
1
1 + _____________
1
2 + _________
1
2 + _____
1
1 + _
5
那么如上所述计算出的中间收敛点为;
1 1 3 7 10 57
_ -> _ -> _ -> _ -> __ -> __ = 1.425
0 1 2 5 7 40
请注意,除了 57/40
是 1.425
.
连分数是一个非常深奥的话题,一旦以连分数形式在它们之间建立算术,实际上就消除了浮点错误。
可以玩here.