【问题标题】:What is the problem of the "else if" condition in this C program?这个 C 程序中的“else if”条件有什么问题?
【发布时间】:2021-10-22 15:46:35
【问题描述】:

我为一个问题创建了一个 C 程序,但我遇到了下面给出的一些问题。我在这个程序中使用了逻辑和条件运算符。

//Question - c4.d.f
/* 
A certain grade of steel is graded according to the following conditions:
(i)Hardness must be greater than 50 
(ii)Carbon content must be less than 0.7
(iii)Tensile strength must be greater than 5600

The grades are as follows:
Grade is 10 if all three conditions are met 
Grade is 9 if conditions (i) and (ii) are met 
Grade 8 if conditions (ii) and (iii) are met
Grade 7 if conditions (i) and (iii) are met
Grade 6 if only one condition is met
Grade is 5 if none of the conditions are met

Write a program, which will require the user to give values of hardness,
carbon content, and tensile strength of the steel under consideration and
output the grade of the steel.
*/

#include<stdio.h>

int main()
{
    int hrd,tslstr;
    float crbct;
    int con1, con2, con3;
    printf("Please enter the values of the Hardness, Carbon content, Tensile Strength\n");
    scanf("%d%f%d",&hrd,&crbct,&tslstr);

    //conditions
    hrd>50?con1=1:(con1=0);
    crbct<0.7?con2=1:(con2=0);
    tslstr>5600?con3=1:(con3=0);

    //Calculating Grades
    if( con1 && con2 && con3)
        printf("Grade 10\n");
    else if( con1 && con2 )
        printf("Grade 9\n");
    else if( con2 && con3 )
        printf("Grade 8\n");
    else if( con1 && con3 )
        printf("Grade 7\n");
    else if( con1 || con2 || con3 )
        printf("Grade 6\n");
    else 
        printf("Grade 5\n");
    
return 0;
}

我运行程序并给出值(如下所示),所以我打印了“Grade 5”,但它打印的是“Grade 6”。请帮我找出这段代码中的问题。

Please enter the values of the Hardness, Carbon content, Tensile Strength
50
0.7
5600
Grade 6

【问题讨论】:

  • 请学习如何使用调试器在监控变量和theif值的同时逐句执行代码。
  • 并且不要做像hrd&gt;50?con1=1:(con1=0);这样的陈述。首选简单的 if else 语句,因为它会使代码更易于阅读和理解,但如果您绝对必须使用三元表达式,请在赋值的右侧使用它(con1 = hdr &gt; 50 ? 1 : 0;,或者考虑到布尔结果是1 为真,0 为假:con1 = hdr &gt; 50;)
  • ... 如果您觉得自己不知道如何使用调试器,请首先打印 con1、con2 和 con3 的值。它应该为您提供有关哪个有问题的线索。例如,您可能会发现 con2 为 1。如果发生这种情况,您将打印 crbct 的值。如果您随后看到它是例如 0.6999999,您就会知道是浮点问题导致了您的问题。

标签: c if-statement conditional-statements logical-operators


【解决方案1】:

crbctfloat,但您将其与 double0.7 进行比较。 floatdouble 算术近似实数算术,它们使用不同的近似值。最接近 0.7 的 float 值恰好小于最接近 0.7 的 double 值,因此 .7f &lt; .7 评估为真。

“修复”程序的最简单方法是与float0.7f 进行比较:

crbct<0.7f ? con2=1 : con2=0;

这将像float 允许的类型一样准确地处理浮点数。它仍然会在输入时出现舍入错误(因此“.6999998”和“.7”的输入都被视为小于 0.7,即使后者显然不是),但不会有任何进一步的错误。 (如果您想完全正确地测试输入是否小于 .7,则必须将其作为字符串读取并手动处理比较,而不使用浮点运算。)

【讨论】:

    【解决方案2】:

    这是由于精度问题。大多数现代 C++ 实现使用 IEEE-754 和 single precision for float。在这种格式中,单精度中最接近 0.7 的是 0.699999988079071044921875。因此小于0.7

    通常如果你真的要比较浮点数,你需要添加一个epsilon(即一个非常小的数字,可以克服精度问题,同时不影响结果)。但正如 cmets 所指出的,这不是一个通用的解决方案,只是与公差进行比较。因此,您必须谨慎服用。您需要考虑它是否适合您的情况。但是,如果你真的想用 epsilon 来做,你的程序可以改变如下:

    只需将相关代码改为

    float eps = (float)1e-6;
    crbct+eps<0.7?con2=1:(con2=0);
    

    【讨论】:

    • 请不要建议与公差进行比较。 There is no general solution for comparing floating-point numbers that contain errors from previous operations.您提出的解决方案会减少误报但会增加误报,因此它不会像您所说的那样“修复”程序;它只是改变了它所拥有的错误类型。此外,您显示的代码实际上在该程序中不起作用;对于问题中的输入,它仍然会产生不想要的输出,“Grade 6”。
    • 我通常将我的值四舍五入到 x 位小数进行比较。
    • @AndrewTruckle:该方法也会引入错误。四舍五入将许多数字移近一点(1.234 和 1.233 到 1.23),但将一些数字移得更远(1.23499 和 1.23501 到 1.23 和 1.24)。
    • @EricPostpischil 它满足了我使用的工具的需求。舍入到 3 dp 通常是在差异出现之前,所以我们得到了匹配。
    • @AndrewTruckle:四舍五入存在已知错误,正如我所演示的。您没有在程序中观察到此类错误这一事实并不能否定在用于此目的时舍入已知错误这一事实。
    【解决方案3】:
    #include<stdio.h>
    
    int main()
    {
        int hrd,tslstr;
        float crbct;
        int con1, con2, con3;
        printf("Please enter the values of the Hardness, Carbon content, Tensile Strength\n");
        scanf("%d%f%d",&hrd,&crbct,&tslstr);
    
        //conditions
        con1 = (hrd>50) ? 1: 0;
        con2 = (crbct<0.7) ? 1 : 0;
        con3 = (tslstr>5600) ? 1 : 0;
    
        //Calculating Grades
        if( con1 && con2 && con3)
            printf("Grade 10\n");
        else if( con1 && con2 )
            printf("Grade 9\n");
        else if( con2 && con3 )
            printf("Grade 8\n");
        else if( con1 && con3 )
            printf("Grade 7\n");
        else if( con1 || con2 || con3 )
            printf("Grade 6\n");
        else 
            printf("Grade 5\n");
        
    return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多