进行斐波那契函数,并且不能正确地添加/表示两位数或更大的整数

时间:2019-03-17 08:38:31

标签: c

这是一个将斐波那契数字加在一起的程序。有问题的功能是hugeAdd。整数正确加到8,但是一旦达到13或更高,就会返回不正确的值。错误的值是进位(1)的内存地址,但是正确的是1(3)的位置。但是,尝试手动设置它,由于某种原因,它似乎不起作用,因为即使在for循环中也无法调用在for语句中声明的计数器变量'k'。

注意:这是我能制造的最小的MCVE。在Fibonacci.c中的第134行处插入一个断点,它将打印出添加的整数。

Fibonacci.h(这是包含struct def等的头文件)

#ifndef __FIBONACCI_H
#define __FIBONACCI_H

typedef struct HugeInteger
{
// a dynamically allocated array to hold the digits of a huge integer
int *digits;

// the number of digits in the huge integer (approx. equal to arraylength)
int length;
} HugeInteger;


// Functional Prototypes

HugeInteger *hugeAdd(HugeInteger *p, HugeInteger *q);

HugeInteger *hugeDestroyer(HugeInteger *p);

HugeInteger *parseString(char *str);

HugeInteger *parseInt(unsigned int n);

unsigned int *toUnsignedInt(HugeInteger *p);

HugeInteger *fib(int n);

double difficultyRating(void);

double hoursSpent(void);


#endif

Testcase4.c类(包含主函数和测试用例到测试函数)

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "Fibonacci.h"

// print a HugeInteger (followed by a newline character)
void hugePrint(HugeInteger *p)
{
int i;

if (p == NULL || p->digits == NULL)
{
    printf("(null pointer)\n");
    return;
}

for (i = p->length - 1; i >= 0; i--)
    printf("%d", p->digits[i]);
printf("\n");
}

int main(void)
{
int i;
HugeInteger *p;

for (i = 0; i <= 1000; i++)
{
    printf("F(%d) = ", i);
    hugePrint(p = fib(i));
    //p = fib(i);
    //hugeDestroyer(p);
}

return 0;
}

Fibonacci.c类(此类具有运行testcase4.c的所有功能)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include "Fibonacci.h"

HugeInteger *hugeAdd(HugeInteger *p, HugeInteger *q)
{
HugeInteger *hugerInt = malloc(sizeof(HugeInteger));

int overhead=1,i,j,results=0;
 int *resultArray = NULL;

if(p == NULL || q == NULL || hugerInt == NULL)
{
    return NULL;
}


if(p->length > q->length)
{
  resultArray = calloc(((p->length)+ overhead), sizeof(int));
  hugerInt->length = p->length;
  hugerInt->digits = malloc(sizeof(int) * (p->length + overhead));

  if(resultArray == NULL)
  {
      return NULL;
  }
  for(int k=0; k < p->length; k++)
  {
    if(k >= q->length)
    {
        results=p->digits[k];   //check for not skipping smaller int
        resultArray[k] = results + resultArray[k];
    }
    else{
 results = p->digits[k] + q->digits[k];
  if(results > 9 )
  {
      if(p->digits[k+1] == 0)
      {
          hugerInt->digits[k+1] = 1;
      }

      resultArray[k+1] = resultArray[k+1] + 1;

      results = results - 10;
    printf("length of resultArray is %d\n",p->length+1);
  }


      resultArray[k] = results;


  }
  }
}
else
{
  resultArray = calloc(((p->length)+ overhead)+ 1, sizeof(int));
  hugerInt->length = q->length;
  hugerInt->digits = malloc(sizeof(int) * (q->length)+ overhead);

  if(resultArray == NULL)
  {
      return NULL;
  }
  for(i=0; i < q->length; i++)
  {
   // printf("q length %d", q->length);
    if(i >= p->length) // Check if second struct passed is smaller then first one passed
    {
        results=q->digits[i];   //check for not skipping smaller int
        resultArray[i] = results;
    }
    else{
 results = q->digits[i] + p->digits[i];
  if(results > 9 )
  {
      printf("I is in larger then 9 check %d", i);
      if(p->digits[i+1] == 0)
      {
          hugerInt->digits[i+1] = 1;
      }

      printf("i is %d\n",i);
      printf("Assigning 1 to %d in resultarray\n", i);
      resultArray[i+1] = 1; // if value is greater then 9 the 1 carries and gets added to the result.(This is the part i think is going wrong) 

      results = results - 10;

    printf("length of resultArray is %d\n",p->length+1);
      printf("results:$d\n", results);
  }


      resultArray[i] = results; // Throws added values into array


    }
  }
}

printf("\n=================\n");
for(i=0; i < hugerInt->length; i++)
{
   hugerInt->digits[i] = resultArray[i];
}


printf("Result array at 0 is %d\n", resultArray[0]); // This is were the 
printf("Result array at 1 is %d\n", resultArray[1]); // added numbers are stored.
printf("Result array at 2 is %d\n", resultArray[2]);

printf("=====================\n");

free(resultArray);
return hugerInt;
} 

HugeInteger *fib(int n)
{
HugeInteger *fibInt = malloc(sizeof(HugeInteger));

HugeInteger *fatherFib = malloc(sizeof(HugeInteger));
HugeInteger *grandfatherFib = malloc(sizeof(HugeInteger));


int j=1,fatherLength=0,grandfatherLength=0,fibLength=0,result, overhead=1;
unsigned int father, grandFather, fib, tempFather, tempGrandfather, tempFib;

fatherFib->digits = calloc((n + overhead),sizeof(int) );
fibInt->digits = calloc((n+overhead),sizeof(int));

grandfatherFib->digits = calloc((n + overhead),sizeof(int) );

  fatherFib->length = 1;
 grandfatherFib->length = 1;
 fibInt->length = 1;

 if(n == 0)
 {
     fibInt->digits[0] = 0;
     return fibInt;
 }



for(int i=0; i < n; i++)
{


 if(i >= 1)
 {

  if(fatherFib->digits[0] >= 5 && grandfatherFib->digits[0] >= 5)
  {
  fibInt->length = 2;

  }
  else if(fatherFib->digits[1] >= 5 && grandfatherFib->digits[1] >= 5)
  {
  fibInt->length = 3;

  }
 }

 if(i == 0)
 {
     fatherFib->digits[0]= 0;
     grandfatherFib->digits[0]=1;
 }



fibInt = hugeAdd(fatherFib,grandfatherFib);

 grandfatherFib = fatherFib;


  if(fibInt->length == 2)
{
    printf("tens value in father fib %d\n", fatherFib->digits[1]);
}
fatherFib = fibInt;


}
 free(grandfatherFib->digits);
 free(grandFatherFib);
 return fatherFib;

}


int power(int base, int numTimes)
{
int result=1,i=0;

if(numTimes == 1)
{
    return base;
}

for(;i < numTimes; i++)
{
    result = result * base;
}
return result;
}

1 个答案:

答案 0 :(得分:2)

在编译代码时考虑警告/错误:(在问题版本之前)

在Fibonacci.c

else if(strlen(str) == 0 && str[0] == "")

str[0] char str[0] == ""从来都不是真的,只是这样做

else if (str[0] == 0)

HugeInteger *hugeDestroyer(HugeInteger *p)
{

   int length;

  // printf("Hiiting destroyer");
   if(p == NULL)
   {
       return;
   }

   length = p->length;

    free(p->digits); // But this works???????

    free(p->length);
    free(p);

 }

您永远不会返回值(指向 HugeInteger 的指针),显然它必须具有签名void hugeDestroyer(HugeInteger *p)(也在标头中)

free(p->length);

您释放了 int 吗?

删除该行以及其他关于 length

的无用行

那么最后

void hugeDestroyer(HugeInteger *p)
{
  // printf("Hiiting destroyer");
  if (p != NULL)
  {
    free(p->digits); // But this works???????
    free(p);
 }
}

     unsigned long long int check = malloc(sizeof(unsigned long long int));

malloc 返回一个地址(指针),实际上您没有使用 check check = nextPow + real也没有用)

难以想象您想做什么,请删除有关 check

的所有内容

 if(p->digits[k+1] == NULL)
 ...
 if(p->digits[i+1] == NULL)

p->digits[k+1] int ,您将其与指针进行比较,将 NULL 替换为0

hugePrint(fibInt);

未知,声明缺失

编译时要求较高的警告/错误检测级别,并根据

纠正代码

关于内存泄漏:

hugeAdd

HugeInteger *test = malloc(sizeof(HugeInteger));
test->length= 1;
test->digits = malloc(sizeof(int));
test->digits[0] = 5;

test 永远不会使用,您只会造成内存泄漏

 resultArray = calloc(((p->length)+ overhead), sizeof(int));

您设置了内容,但从未释放它,这是另一个内存泄漏

fib

HugeInteger *grandfatherFib = malloc(sizeof(HugeInteger));

您从不释放 grandfatherFib 这是另一个内存泄漏


关于结果:

  • fib(0)= 0:确定
  • fib(1)= 1:确定
  • fib(2)= 2:确定
  • ...
  • fib(6)= 8:好
  • fib(7)= 13:好的
  • fib(8)= 11:ko

您的问题是,您不能很好地添加至少2位数字,例如,如果我将 hugeAdd 的结尾稍加更改以替换

 printf("Result array at 0 is %d\n", resultArray[0]); // This is were the 
 printf("Result array at 1 is %d\n", resultArray[1]); // added numbers are stored.
 printf("Result array at 2 is %d\n", resultArray[2]);
 printf("=====================\n");

更实用

printf("=====================\n");
hugePrint(p);
puts("+");
hugePrint(q);
puts("=");
hugePrint(hugerInt);
printf("=====================\n");

然后我显示fib(8)

...
=====================
08
+
5
=
13
=====================
13
tens value in father fib 0
I is in larger then 9 check 0i is 0
Assigning 1 to 0 in resultarray
length of resultArray is 3
results:1

=================
=====================
13
+
08
=
11
=====================

您错过了进位: 8 + 3 = 11 所以 1 1 进位添加到 1 以具有 21 而不是 11

拥有

if(results > 9 )
{
  printf("I is in larger then 9 check %d", i);
  if(p->digits[i+1] == 0)
  {
    hugerInt->digits[i+1] = 1;
  }

不够,因为必须添加进位,如果值是0(没有别的,只有0变成1),则不能设置为1。当然,您可能需要考虑几个更改,将1的进位加到999会产生1000