行在开关内时返回“NaNs”;当开关被注释掉时,其中一些相同的行可以完美运行

问题描述 投票:0回答:1

当我使用 switch 语句运行我的程序(使用 gcc -std=c99 -lm)时,此行中计算的所有“因素”:

factors[rows][0]=cbrtf((3+(float)scores[rows][1])/(3+(float)scores[rows][3]));

被报告为“NaN”。如果我注释掉 switch 语句,同一行将完美运行。谁能解释一下?

作为一个单独的问题,其他开关案例:

factors[rows][0]=((float)scores[rows][1])/(((float)scores[rows][1])+((float)scores[rows][3]));

factors[rows][0]=log((((float)scores[rows][1])/(((float)scores[rows][1])+((float)scores[rows][3] )))+1);

导致 NaN,无论是在开关内部还是外部。我已经检查了我的 paretheses 十几次。不可能被零除(因为分母中的分数之和必须为正),并且为了防止取零的自然对数,这是未定义的,我将 1 添加到始终介于 0 和 1 之间的商包括的。为什么这些线会产生 NaN?

这是自 1973 年 Fortran IV 简介以来我编写的第一个程序,因此它可能是显而易见的。 . .

这是一大块代码:

//int iPreference=0;
//printf("\n1\tCube root of (Points scored by Team A + 3)/(Points scored by Team B + 3)\n");
//printf("2\tFraction of game points scored by Team A\n");
//printf("3\tln of [(percentage of game points scored by Team A) + 1]\n");
//printf("\nPlease select your preference (1-3): ");
//scanf("%d", &iPreference);

for (rows=0; rows<games; rows++)
{
    scores[rows][0]=values[rows].iA_ID;
    scores[rows+games][0]=values[rows].iB_ID;
    scores[rows][1]=values[rows].iA_Points;
    scores[rows+games][1]=values[rows].iB_Points;
    scores[rows][2]=values[rows].iB_ID;
    scores[rows+games][2]=values[rows].iA_ID;
    scores[rows][3]=values[rows].iB_Points;
    scores[rows+games][3]=values[rows].iA_Points;
    scores[rows][4]=0;  // Column 4 will be checked off with a '1' once a game has been evaluated
    scores[rows+games][4]=0;
    factors[rows][1]=1;  // Seed every team with a starting value of 1
    factors[rows+games][1]=1;
    //switch (iPreference)
    //{
    //  case 1:
            factors[rows][0]=cbrtf((3+(float)scores[rows][1])/(3+(float)scores[rows][3]));
            factors[rows+games][0]=cbrtf((3+(float)scores[rows+games][1])/(3+(float)scores[rows+games][3]));
    //  case 2:
    //      factors[rows][0]=((float)scores[rows][1])/(((float)scores[rows][1])+((float)scores[rows][3]));  
    //      factors[rows+games][0]=((float)scores[rows+games][1])/(((float)scores[rows+games][1])+((float)scores[rows+games][3]));
    //  case 3:
    //      factors[rows][0]=log((((float)scores[rows][1])/(((float)scores[rows][1])+((float)scores[rows][3])))+1); 
    //      factors[rows+games][0]=log((((float)scores[rows+games][1])/(((float)scores[rows+games][1])+((float)scores[rows+games][3])))+1);
    //}
}
c switch-statement nan
1个回答
0
投票

随着立方根变小,它们可能会达到范围为 [3.410^-38, 3.410^38] 的浮点数的极限,在这种情况下,您需要使用 double 和

cbrt()
将增加范围并避免除以零。

添加打印语句以了解 NaN 发生的原因/时间可能会很好:

// add this at the top if you don't already have it
#include <stdio.h>  

/* place this somewhere before the case statement */
float custom_NAN = 0.0/0.0;

/* place this somewhere after you set factors[rows][0] 
   to stop the program when you hit a NaN.  Remove  
   exit(0) if you want this to continue after computing a NaN
*/
if ( factors[rows][0] == custom_NAN ) {
     // print the numerator and denominator 
     printf("\tNumerator:(%E) / Denominator(%E) = %E\n", (float)scores[rows][1], ((float)scores[rows][1]+(float)scores[rows][3]), (float)scores[rows][0]);
     // end the program and review 
     exit(0);
}
© www.soinside.com 2019 - 2024. All rights reserved.