【问题标题】:Sum of first n natural numbers前 n 个自然数之和
【发布时间】:2020-12-28 04:04:12
【问题描述】:

尝试学习 C 我正在玩一些 for 循环和求和。我想在不使用数学公式n(n+1)/2 的情况下计算第一个n 自然数的总和。我有这个代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int n = 100;
    int sum = 0;

    for (int ix = 0; ix <= n; ix++) {
        sum = sum + ix;
    }

    printf("Sum of the first %d natural numbers is %d\n", n, sum);
}

所以对于n = 100,我得到的总和是5050,这是正确的。当我使用n = 10000 时,我也得到了正确的答案,但是如果我去例如n = 1000000,那么我会得到sum = 1784293664,但正确的答案应该是sum = 500000500000

为什么当n 变大时我的程序停止工作?n = 1000000 时显示的总和是多少?

【问题讨论】:

  • 这能回答你的问题吗? C integer overflow
  • printf("%f\n", (n * (n + 1.0)) / 2);
  • 如果你使用 unsigned int,你可以将最大值加倍,但它仍然会溢出你想要做的事情。你能做的最好的就是 unsigned long long int,除非你有创意并使用一个额外的变量来存储最高有效数字,一旦它们对于数据类型来说太大了(只要知道它们实际上被除以 10 )。例如。 2878 可以是 num1 为 2 和 num2 为 878。en.wikipedia.org/wiki/C_data_types
  • @chux-ReinstateMonica 我的意思是溢出前的最大输出,但是是的,只有溢出前最大输入 n 的大约 1.414 倍。数学很好。

标签: c loops for-loop sum integer


【解决方案1】:

如果您想计算自然数的总和,那么请使用 unsigned int 类型而不是 int 类型。

相应地将变量sum声明为具有unsigned long long int类型以减少溢出的风险。

例如

unsigned int n = 100;
unsigned long long int sum = 0;

for ( unsigned int ix = 1; ix <= n; ix++){
   sum = sum + ix;
}

printf("Sum of the first %u natural numbers is %llu\n" , n, sum);

或者您可以包含标题 &lt;inttypes.h&gt; 并为变量 sum 使用类型 uintmax_t,如下面的演示程序所示。

#include <stdio.h>
#include <inttypes.h>

int main(void) 
{
    unsigned int n = 1000000;
    uintmax_t sum = 0;

    for ( unsigned int ix = 1; ix <= n; ix++){
       sum = sum + ix;
    }

    printf("Sum of the first %u natural numbers is %" PRIuMAX "\n" , n, sum);
    
    return 0;
}

程序输出是

Sum of the first 1000000 natural numbers is 500000500000

注意这里不需要引入辅助变量ix。循环可以看起来更简单,例如

#include <stdio.h>
#include <inttypes.h>

int main(void) 
{
    unsigned int n = 1000000;
    uintmax_t sum = 0;

    while ( n ) sum += n--;
    
    printf( "Sum of the first %u natural numbers is %" PRIuMAX "\n" , n, sum );
    
    return 0;
}

【讨论】:

  • 感谢您的帮助。但是,我不明白一个类型如何可以是 long long 和 int?你能详细说明一下吗?
  • @Parseval 有以下整数类型,例如有符号类型 int 或有符号或有符号 int、long 或 long int、long long 或 long long int。
  • @Parseval: shortlongsignedunsigned 是类型说明符,可以与 int 或没有其他具有相同语义的类型说明符组合:long long x;long long int x;long int long x;int long long x; 是等价的定义。
【解决方案2】:

您正在达到变量类型“int”的限制。尝试使用长数据类型来存储总和。

【讨论】:

  • 感谢您的回答。不幸的是,长数据类型并没有解决问题。
【解决方案3】:

int 类型太小,无法包含这么大的数字,所以在上面的过程中会发生算术溢出。您观察到的行为称为未定义行为(简称 UB),这是有符号整数溢出时在 C 中正式发生的情况(无符号整数只是翻转为零并继续)。

【讨论】:

  • 您好,感谢您的回答。但这是否意味着在 C 语言中无法处理大量数字,或者有没有办法解决这个问题?我想计时这个操作,也就是想知道计算前n个自然数需要多长时间。
  • 除非你想自己实现,否则你使用专门处理大数的库,比如gmplib.org
  • en.m.wikipedia.org/wiki/…之类的东西,请参阅Language专栏中的C语言库。
【解决方案4】:

#include int main(){

int i=0, sum=0, n=10;

while(i<=n){
    printf("%d\n",i);
   sum=sum+i;
i++;
}
printf("%d",sum);

返回 0; }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多