【问题标题】:Write a program to find the sum of positive odd numbers and the product of positive even numbers less than or equal to 30编写程序求正奇数之和与小于或等于 30 的正偶数之积
【发布时间】:2013-04-30 23:01:49
【问题描述】:

我在为这个问题编写 C 程序时遇到了一些问题。也许我读错了问题并且做错了。有人可以帮我吗?这就是我正在尝试的方式

#include<stdio.h>
void main(void)
{
    int j, sum=0;
    long int product=1;
    for(j=1;j<=30;j=j+2)
    {
        sum=sum+j;
    }
    for(j=2;j<=30;j=j+2)
    {
        product=product*j;
    }
    printf("\nThe sum of positive odd numbers is: %d", sum);
    printf("\nThe product of positive even numbers is: %d", product);
}

我得到的输出是:

The sum of positive odd numbers is: 225
The product of positive even numbers is: -1409286144

我弄错了产品部分。我尝试过使用 unsigned long int、long long、unsigned long long。没有任何效果。

【问题讨论】:

  • 您的产品超出了存储类型的限制。尝试从long int 换成更大的存储类型。
  • 2*4*8...*28 给出大约 30 位数字。你几乎需要一个浮点类型来保存它。值得一提的是:N 个连续奇数的总和(从 1 开始)得出 N 的平方,因此您可以更快更轻松地计算该部分。
  • 改用模数将代码压缩为 1 个循环。伪代码 - for (j=1,j
  • 您的答案应该正好适合 64 位整数。
  • 这个简单产品的庞大规模是一个温和的提醒,我们应该生活在对具有阶乘时间复杂度的算法的恐惧中! =)

标签: c types int


【解决方案1】:

尝试在您的printf 中使用%ld 而不是%d

printf("\nThe product of positive even numbers is: %ld", product);

因为它是long int 而不是int

如果你使用long long int,你会想要%lld。鉴于这是一个非常非常大的产品,您可能需要 long long 尺寸。我不知道你平台的long int是32位还是64位,但这里肯定需要一个64位的数字。

long long 格式字符串可能会因您的确切平台和编译器而异,但如今大多数事情都已在 %lld 上标准化。特别是,旧的 Microsoft 编译器有时会使用 %I64d

【讨论】:

  • @StilesCrisis 恐怕printf() 中的%ld 在我的编译器Mingw 和ideone ideone.com/GRSMLE 中都会产生不正确的输出(负数)
  • @SheerFish:您处于 32 位模式,您看到的是溢出。在 32 位平台上,要获得正确的结果,您必须使用 long long int
【解决方案2】:

就所有小于 30 的奇数之和而言,没有问题,因为它只是 225。但是小于 30 的所有偶数(或奇数)的乘积是 巨大数字。为此,您需要具有更大容量的数据类型。在以下程序中,我只是使用double 而不是long int 来表示product,并且我使用了%e 格式说明符来在prinf() 中以简洁的方式显示产品,但您也可以使用%f

#include<stdio.h>


int main(void)    //Return type of main() is "int",not "void" as you've used
{
    int j, sum=0;
    double product=1;   //Change type of "product" to "double"

    for(j=1;j<=30;j=j+2)
    {
        sum=sum+j;
    }
    for(j=2;j<=30;j=j+2)
    {
        product=product*j;
    }

    printf("The sum of positive odd numbers is: %d\n", sum); 
    printf("The product of positive even numbers is: %e",product); //Use %e 
}

输出 The sum of positive odd numbers is: 225

       The product of positive even numbers is: 4.284987e+16

【讨论】:

  • @RaedShahid %ld in printf() 是否按照上面建议的海报解决了您的问题?它发现结果不正确。 ideone.com/GRSMLE
  • double 可能会提供一个接近的近似值,但不太可能得到实际的正确答案。根据您的需要,它可能就足够了。 long long int 将是精确的,但当结果增长 > 2^64 时也会开始失败,而 double 将继续工作,但精度会降低。
  • @Rüppell'sVulture 不是真的。它确实给出了不正确的结果,所以我不得不使用long long int
  • @RaedShahid long long int 在我的 32 位系统上给出了正确的结果,但是 long int 存在溢出。所以 StilesCrisis 是对的,只是 long int 在 32 位系统中是不够的像我一样。
【解决方案3】:

计算使用 unsinged int (32bit)

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

typedef unsigned short UInt16;
typedef unsigned UInt32;
typedef struct _unums {
    size_t size;
    UInt16 *nums;//array 
} UNums;

void UNums_init(UNums *num, UInt16 n){
    num->nums = malloc(sizeof(UInt16));
    num->nums[0] = n;
    num->size = 1;
}

void UNums_mul(UNums *num, UInt16 n){
    UInt16 carry = 0;
    size_t i;

    for(i=0;i<num->size;++i){
        UInt32 wk = n;
        wk = wk * num->nums[i] + carry;
        num->nums[i] = wk % 10000;
        carry = wk / 10000;
    }
    if(carry){
        num->size += 1;
        num->nums = realloc(num->nums, num->size * sizeof(UInt16));
        num->nums[i] = carry;
    }
}

void UNums_print(UNums *num){
    size_t i = num->size;
    int w = 0;
    do{
        --i;
        printf("%0*hu", w, num->nums[i]);
        if(!w) w = 4;
    }while(i!=0);
}

void UNum_drop(UNums *num){
    free(num->nums);
    num->nums = NULL;
}

int main( void ){
    UNums n;
    UInt16 i;
    assert(sizeof(UInt32) == 4);//32bit
    assert(sizeof(UInt16) == 2);//16bit

    UNums_init(&n, 1);
    for(i=2;i<=30;i+=2)
        UNums_mul(&n, i);
    UNums_print(&n);//42849873690624000
    UNum_drop(&n);
    return 0;
}

【讨论】:

  • 投反对票的原因是什么?如果程序有错误,请告诉我。
  • 不是我。但我不明白你在这里做了什么,而且我在 C 语言中很新手,你可以从我问的问题中看出:p
  • Okey-dokey 你写过乘法计算吗?
猜你喜欢
  • 2015-10-24
  • 2019-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多