- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我编写了这段代码来生成平方根 N 的连分数。
但当 N = 139 时失败。
输出应该是 {11,1,3,1,3,7,1,1,2,11,2,1,1,7,3,1,3,1,22}
虽然我的代码给出了 394 个术语的序列......其中前几个术语是正确的,但当它达到 22 个时,它给出 12 个!
有人可以帮我解决这个问题吗?
vector <int> f;
int B;double A;
A = sqrt(N*1.0);
B = floor(A);
f.push_back(B);
while (B != 2 * f[0])) {
A = 1.0 / (A - B);
B =floor(A);
f.push_back(B);
}
f.push_back(B);
最佳答案
根本问题是您不能将非平方的平方根精确地表示为 float 。
如果ξ
是精确值,x
近似值(这应该还是相当不错的,所以特别是 floor(ξ) = a = floor(x)
仍然成立),那么在下一步连分式算法之后的差异是
ξ' - x' = 1/(ξ - a) - 1/(x - a) = (x - ξ) / ((ξ - a)*(x - a)) ≈ (x - ξ) / (ξ - a)^2
因此我们看到,在每一步中,近似值与实际值之间的差值的绝对值都会增加,因为 0 < ξ - a < 1
.每次出现较大的偏商(ξ - a
接近于 0)时,差值都会增加一个很大的因子。一旦差(的绝对值)为 1 或更大,下一个计算的偏商肯定是错误的,但很可能第一个错误的偏商出现得更早。
Charles mentioned与 n
的原始近似值的近似值正确的数字,你可以计算大约n
连分数的偏商。这是一个很好的经验法则,但正如我们所见,任何大的偏商都需要更高的精度,从而减少可获得的偏商的数量,有时您会更早地得到错误的偏商。
案例√139
是一个相对较长的周期,有几个大的偏商,所以第一个错误计算的偏商出现在周期完成之前就不足为奇了(我很惊讶它没有出现得更早)。
使用浮点运算,无法避免这种情况。
但是对于二次方的情况,我们可以通过仅使用整数运算来避免该问题。假设您要计算的连分式展开
ξ = (√D + P) / Q
哪里Q
划分 D - P²
和 D > 1
不是一个完美的正方形(如果不满足整除条件,您可以将 D
替换为 D*Q²
,将 P
替换为 P*Q
并将 Q
替换为 Q²
;您的情况是 P = 0, Q = 1
,其中是微不足道的满足)。将完整的商写为
ξ_k = (√D + P_k) / Q_k (with ξ_0 = ξ, P_0 = P, Q_0 = Q)
并表示偏商 a_k
.然后
ξ_k - a_k = (√D - (a_k*Q_k - P_k)) / Q_k
并且,用P_{k+1} = a_k*Q_k - P_k
,
ξ_{k+1} = 1/(ξ_k - a_k) = Q_k / (√D - P_{k+1}) = (√D + P_{k+1}) / [(D - P_{k+1}^2) / Q_k],
所以 Q_{k+1} = (D - P_{k+1}^2) / Q_k
— 自 P_{k+1}^2 - P_k^2
是 Q_k
的倍数, 通过归纳 Q_{k+1}
是一个整数并且Q_{k+1}
划分 D - P_{k+1}^2
.
实数的连分数展开ξ
是周期性的当且仅当ξ
是二次surd,当上述算法中第一对(P_k, Q_k)
时,周期结束重复。纯平方根的情况特别简单,第一个Q_k = 1
时结束对于 k > 0
, 和 P_k, Q_k
总是非负的。
与 R = floor(√D)
, 偏商可以计算为
a_k = floor((R + P_k) / Q_k)
所以上述算法的代码就变成了
std::vector<unsigned long> sqrtCF(unsigned long D) {
// sqrt(D) may be slightly off for large D.
// If large D are expected, a correction for R is needed.
unsigned long R = floor(sqrt(D));
std::vector<unsigned long> f;
f.push_back(R);
if (R*R == D) {
// Oops, a square
return f;
}
unsigned long a = R, P = 0, Q = 1;
do {
P = a*Q - P;
Q = (D - P*P)/Q;
a = (R + P)/Q;
f.push_back(a);
}while(Q != 1);
return f;
}
可以轻松计算(例如)√7981
的连分数周期长度为 182。
关于c++ - 生成平方根的连分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12182701/
出于某种原因,我的平方根程序得到的答案与大多数输入应得到的答案略有不同。我不确定这是为什么。只有某些输入是错误的。在给出答案后的最后我也遇到了段错误,我不确定为什么会这样。 #include #inc
我目前正在实现一个可以处理与物理单位相关的数字数据的类。 我想实现一种计算实例平方根的方法。假设您有一个具有属性值和名称的类的实例: from math import sqrt class Foo:
我正在使用 HTML + CSS + AngularJS 制作一个简单的计算器。一切正常,但我想添加一个 SquareRoot 函数。这是一些代码: function _solve(){ switc
问题是关于在通用数值接口(interface)中定义平方根算法的问题的策略方法。我知道存在解决不同条件下问题的算法。我对以下算法感兴趣: 仅使用选定的函数解决问题; 不关心操作的对象是整数、 floa
好吧,我已经研究了一段时间了,我知道我的逻辑是正确的,但是,我似乎无法生成正数的正确底平方根。 public int mySqrt(int x) { if(x 0) uppe
我找不到让这个函数 Math.sqrt(value) 工作的方法。 (╯°□°)╯︵┻━┻我不确定,但问题似乎出在运营商。我还尝试在 const calculation 中添加该函数,但它也不起作用。
我发现了这段获得平方根的代码,令我惊讶的是它的工作方式,使用 union 和位移这是代码: float sqrt3(const float x) { union { int i;
在 python 中使用 sqrt 函数时,我遇到了“distance ValueError: math domain error”问题。 这是我的代码: from math import sqrt
我一直在做一些研究,寻找一种对大整数进行运算的相对快速的平方根算法。我在这里找到了几个例程。第一个(下面)是用 C 语言编写的... int isqrt(int n) { int b = 0;
好吧,我想知道 math.h 平方根与其中包含神奇数字的那个(因 Quake 而出名,但由 SGI 制作)相比有多快。 但这对我来说是一个受伤的世界。 我首先在 Mac 上尝试了此操作,其中 math
有谁知道如何解决这个复发? 大定理在这里不起作用。 最佳答案 这在 O(1) 中似乎很明显,因为 T(n) = T(n - sqrt(n)) = T(m) with 0 < m < n 通过归纳,你得
我是一名优秀的程序员,十分优秀!