【问题标题】:Calculating square root for extremely large numbers in C [duplicate]在C中计算极大数的平方根[重复]
【发布时间】:2018-01-09 20:37:38
【问题描述】:

我正在解决学校奥林匹克竞赛的一些任务,但我被困在一个问题上。我找到了任务的解决方案,但我的解决方案需要平方根。我的代码适用于前 12 个输入,但随后给出了错误的答案。我猜这是由于输入非常大,可能高达 10^400000。所以我想知道是否有办法计算C中这些极大输入的平方根的整数部分。这是代码:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
    long long n;
    scanf("%lld", &n);
    long long ans;
    ans = sqrtl(n-1);
    long long result;
    result = ans+1-llabs(n-ans*ans-(ans+1));
    printf("%lld\n", result);
    return 0;
}

【问题讨论】:

  • 这样一个挑战的想法不是使用内置的sqrt函数,而是使用你自己的算法。
  • 如果不允许使用第三方库,您将不得不研究平方根算法并实施自己的解决方案。另请参阅this approach
  • @tadman:安全总比抱歉好。也就是说,sqrt(10**400000) = 10**200000.
  • 10^400000那么大?!你确定你不是指10^40?较大的值无法以本机类型表示,甚至long double 也不行。您将不得不使用第三方 bignum 库,或者学习如何实现自己的库。
  • 数字是否用 10^n 表示法?如果是这样,这可能很容易。

标签: c algorithm math limits


【解决方案1】:

简而言之,你可以通过二分法来滚动一个长平方根算法,如下所示:

  • 选择长数字表示(无符号整数数组);

  • 实现长加减法(非常简单,除了进位);

  • 实现减半(也需要注意进位);

  • 实现长比较(类似于减法)。

[请注意,加法允许您实现加倍和四倍,减半也产生除以四。]

然后设置d= 1 并重复加倍d 直到d² &gt; N。 (每次你加倍d,你就加倍。)

接下来,设置a= 0 使得不变量

a² ≤ N < (a + d)²

成立,并在保持不变性的同时反复将d 减半。这是通过

d= d/2; 如果N &lt; (a + d)²,则设置a= a + d;否则保持a 不变。

最后,你会缩小到

a² ≤ N < (a + 1)²

所以a 是整数平方根。

评估条件

N < (a + d)² = a² + 2ad + d²,

N - a² < 2ad + d²,

只需跟踪术语N - a²2ad 并在修改da 时更新它们。这只需要前面提到的原始操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 2017-04-30
    • 2016-02-27
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多