生成2的平方根数字

Qui*_*tic 16 python algorithm numerical-methods sqrt

我想生成两到三百万个数字的平方根数字.

我知道Newton-Raphson,但由于缺乏大整数支持,我不知道如何在C或C++中实现它.有人能指出我正确的方向吗?

另外,如果有人知道如何在python中做到这一点(我是初学者),我也会很感激.

小智 8

您可以尝试使用映射:

a/b -> (a+2b)/(a+b)从...开始a= 1, b= 1.这收敛于sqrt(2)(实际上给出了它的连续分数表示).

现在关键点:这可以表示为矩阵乘法(类似于斐波那契)

如果a_n和b_n是步骤中的第n个数字

[1 2] [a_n b_n] T = [a_(n + 1)b_(n + 1)] T
[1 1]

现在给了我们

[1 2] n [a_1 b_1] T = [a_(n + 1)b_(n + 1)] T
[1 1]

因此,如果2x2矩阵是A,我们需要计算A n,这可以通过重复平方来完成,并且只使用整数运算(因此您不必担心精度问题).

另请注意,您获得的a/b将始终为缩小形式(如gcd(a,b)= gcd(a + 2b,a + b)),因此如果您考虑使用分数类来表示中间体结果,不要!

由于第n个分母类似于(1 + sqrt(2))^ n,要获得300万个数字,您可能需要计算直到第3671656 术语.

请注意,即使您正在寻找~360万个术语,重复平方也可以让您计算O(Log n)乘法和加法中的第n项.

此外,这可以很容易地平行,不像像Newton-Raphson等迭代的那样.


sen*_*rle 7

编辑:我比以前更喜欢这个版本.这是一个接受整数和小数分数的通用解决方案; 当n = 2且精度= 100000时,大约需要两分钟.感谢Paul McGuire提出的建议和其他建议!

def sqrt_list(n, precision):
    ndigits = []        # break n into list of digits
    n_int = int(n)
    n_fraction = n - n_int

    while n_int:                            # generate list of digits of integral part
        ndigits.append(n_int % 10)
        n_int /= 10
    if len(ndigits) % 2: ndigits.append(0)  # ndigits will be processed in groups of 2

    decimal_point_index = len(ndigits) / 2  # remember decimal point position
    while n_fraction:                       # insert digits from fractional part
        n_fraction *= 10
        ndigits.insert(0, int(n_fraction))
        n_fraction -= int(n_fraction)
    if len(ndigits) % 2: ndigits.insert(0, 0)  # ndigits will be processed in groups of 2

    rootlist = []
    root = carry = 0                        # the algorithm
    while root == 0 or (len(rootlist) < precision and (ndigits or carry != 0)):
        carry = carry * 100
        if ndigits: carry += ndigits.pop() * 10 + ndigits.pop()
        x = 9
        while (20 * root + x) * x > carry:
                x -= 1
        carry -= (20 * root + x) * x
        root = root * 10 + x
        rootlist.append(x)
    return rootlist, decimal_point_index
Run Code Online (Sandbox Code Playgroud)