1

我写了几个函数,并检查了多次,看看我写的公式是否错误或任何定义的变量,但这些似乎是正确的。测试用例是由我的导师提供的,所以我认为这些用例必须能够工作!我不确定我的代码中的问题出在哪里或什么地方。顺便说一句,直到最后一个函数的所有先前函数的测试用例都通过了,它只是最后一个函数,estimateYield 给我带来了问题。

注意:我已经声明了很多常量变量,其中一些现在似乎没有使用,但你可以忽略它。

#include "grove.h"
#include <math.h>
#include <stdlib.h>

#define SOILQUALACONST 10 /* Number subtracted from both x and y in typeA. */
#define SOILQUALBCONST 10 /* Number subtracted from both x and y in typeB. */
#define SUNEXPXTERM 8   /* Number you subtract from x in exponent.*/
#define SUNEXPDIV1 10   /* First denominator term in first fraction in exp.*/
#define SUNEXPYTERM 12   /* Number you subtract from y in exponent.*/
#define SUNEXPDIV2 5   /* Second denominator term in second fraction in exp.*/
#define SUNEXPEMULT 10   /* The constant you are multiplying e^(exp.) by.*/
#define IRRIEXPONUM 10   /* The numerator in irrigation exposure function.*/
#define ESTYIELDNUM1 7   /* First term in fraction part of estimated yield.*/
#define ESTYIELDNUM2 7   /* Last term in fraction part of estimated yield.*/

double soilQuality(int x, int y) {
   double typeA, typeB, soilQual;

   typeA = 1 + (sqrt((pow(x - SOILQUALACONST, 2)) + (pow(y - SOILQUALACONST, 2))      * (1.0)));
   typeB = (1 + ((abs(x - SOILQUALBCONST) + abs(y - SOILQUALBCONST))/(2.0)));
   soilQual = (((x + y) % 2) * typeB) + ((1 - ((x + y) % 2)) * typeA);

   return soilQual;
}

double sunExposure(int x, int y) {
   double exponent, sunexp;

   exponent = (-0.5) * (((pow(x - SUNEXPXTERM, 2))/(SUNEXPDIV1)) + ((pow(y -
      SUNEXPYTERM, 2))/(SUNEXPDIV2)));
   sunexp = SUNEXPEMULT * exp(exponent);

   return sunexp;
}

double irrigationExposure(int x, int y) {
   double denominator, waterexp;

   denominator = (1 + abs(x - y)) * (1.0);
   waterexp = ((IRRIEXPONUM)/(denominator));

   return waterexp;
}

double estimateYield(int x, int y) {
   double waterexp, soilqual, sunexp, numerator, estyield;

   waterexp = irrigationExposure(x, y);
   soilqual = soilQuality(x, y);
   sunexp = sunExposure(x, y);

   numerator = ((ESTYIELDNUM1) - (abs(waterexp - ESTYIELDNUM2))) + 1;
   estyield = (soilqual) * (sunexp) * ((numerator)/(2.0));

   return estyield;
}

所以基本上,最后一个函数的一些测试用例一直失败,我似乎无法弄清楚为什么。以下是我的导师暗示的测试用例:

#include <stdio.h>
#include "grove.h"
#include "checkit.h"

int main(){

   checkit_double(estimateYield(3,3), 0.023697  );
   checkit_double(estimateYield(1,19),0.067322 );
   checkit_double(estimateYield(7,8),  20.165240 );
   checkit_double(estimateYield(12,3),  0.007501);
   checkit_double(estimateYield(4,17), 2.371061);

   return(0);
}

这是我运行它们时得到的结果:

Test passed on line 6.
Test FAILED on line 7.  estimateYield(1,19) is 0.088215, expected 0.067322.
Test passed on line 8.
Test passed on line 9.
Test FAILED on line 10.  estimateYield(4,17) is 2.766238, expected 2.371061.

以防万一您需要它,estimateYield 的公式是:

土壤质量(x,y) * sunExposure(x,y) * ((7-(abs(irrigationExposure(x,y) - 7)) + 1)/(2))

4

1 回答 1

4

问题在这里:

numerator = ((ESTYIELDNUM1) - (abs(waterexp - ESTYIELDNUM2))) + 1;

abs您正在使用带有值的整数函数,double因此您会得到一个截断的int结果。更改此行以使用fabs似乎可以解决问题:

numerator = ((ESTYIELDNUM1) - (fabs(waterexp - ESTYIELDNUM2))) + 1;

这是混合整数和浮点运算时的常见问题。我建议您制作所有常量和int变量double,并始终使用浮点运算(和fabs()!)。

另请注意,这gcc -Wall -Wconversion ...会为您发现错误:

$ gcc -Wall -Wconversion soil.c 
soil.c:58:48: warning: implicit conversion turns floating-point number into integer: 'double' to 'int' [-Wconversion]
   numerator = ((ESTYIELDNUM1) - (abs(waterexp - ESTYIELDNUM2))) + 1;
                                  ~~~ ~~~~~~~~~^~~~~~~~~~~~~~
于 2013-10-08T08:06:46.973 回答