我的变量的范围有什么问题?

时间:2015-11-18 11:59:25

标签: c

我几乎没有编程经验,但我必须编写一个简单的C程序,它计算作为温度T的函数的比热(Cp)。 温度范围分成较小的范围,以获得Cp的准确值。

#include <stdio.h>  
#include <math.h>

int main()
{    
    float T, cp1, cp2, cp3, cp4, cp5, cp6, cp7, cp8;                     /*variables */  

    printf( "Please enter temperature in Kelvin\n" );  /* Asks for temperature */
    scanf( "%f", &T );

    cp1=1.67662377469456E-11*pow(T,6.)-4.1197828092268E-08*pow(T,5.)+0.0000418869586791152*pow(T,4.)-0.0225003443462658*pow(T,3.)+6.72987826198519*pow(T,2.)-1062.18721205927*T+73195.8387080729;
    cp2=0.00525246395569212*pow(T,4.)-12.9485474717992*pow(T,3.)+11970.600895997*pow(T,2.)-4918448.82178862*T+757825839.152518;
    cp3=6.63085194968153*pow(T,4.)-17170.4000395659*pow(T,3.)+16673480.6519115*pow(T,2.)-7196031423.69135*T+1164647463146.08;
    cp4=-68.0819524480029*pow(T,5.)+222554.556013276*pow(T,4.)-291004129.724188*pow(T,3.)+190252342532.153*pow(T,2.)-62191220562433.3*T+8131793672657510;
    cp5=9974.74747475981*pow(T,3.)-19674382.9004572*pow(T,2.)+12935329616.4157*T-2834856258114.32;
    cp6=-4.14962557364299E-07*pow(T,6.)+0.000462300031790556*pow(T,5.)-0.0310330512189478*pow(T,4.)+62.8598088326175*pow(T,3.)-189691.032172151*pow(T,2.)+77129922.3433911*T-4056849697.67083;
    cp7=1.47773054803578E-08*pow(T,6.)-0.0000239186385308144*pow(T,5.)+0.00563616606939476*pow(T,4.)+1.50391266948934*pow(T,3.)+9118.7111011683*pow(T,2.)-8897122.07353999*T+2172208386.41784;
    cp8=-4.6626284146362E-08*pow(T,5.)+0.000192659539297423*pow(T,4.)-0.318404373982708*pow(T,3.)+263.141418952148*pow(T,2.)-108775.736711323*T+18001673.992402;


    if (T>=280. && T<=599.9) {                      /* 1st temp range !!! If 599.9 is entered, the program calculates cp2 instead of cp1*/ 
        printf ("1st range Cp= %.6f J/kgK",cp1);                    /* returns cp1 */
    }
    else if (T>599.9 && T<=646.8) {            /* 2nd temp range */ 
        printf("2nd range Cp= %.6f J/kgK",cp2);                 /* returns cp2 */
    }
    else if (T>646.8 && T<=651.2) {            /* 3rd temp range !!! If 651.2 is entered, the program calculates cp4 instead of cp3*/ 
        printf("3rd range Cp= %.6f J/kgK",cp3);                 /* returns cp3 */
    }
    else if (T>651.2 && T<=655.8) {            /* 4th temp range */ 
        printf("4th range Cp= %.6f J/kgK",cp4);                 /* returns cp4 */
    }
    else if (T>655.8 && T<=656.6) {            /* 5th temp range */ 
        printf("5th range Cp= %.6f J/kgK",cp5);                 /* returns cp5 */
    }
    else if (T>656.6 && T<=662.) {            /* 6th temp range */ 
        printf("6th range Cp= %.6f J/kgK",cp6);                 /* returns cp6 */
    }
    else if (T>662. && T<=700.) {            /* 7th temp range */ 
        printf("7th range Cp= %.6f J/kgK",cp7);                 /* returns cp7 */
    }
    else if (T>700. && T<=900.) {            /* 8th temp range */ 
        printf("8th range Cp= %.6f J/kgK",cp8);                 /* returns cp8 */
    }
    else {
        printf("Cp= 4180 J/kgK");     /* Executed if no other statement is */
    }

  return 0;
}

代码可能不是很优雅,但除了第1范围和第3范围外它都有效。

第一个范围

if (T>=280. && T<=599.9) {                      /* 1st temp range If 599.9 is entered, the program calculates cp2 instead of cp1*/ 
        printf ("1st range Cp= %.6f J/kgK",cp1);                    /* returns cp1 */
    }

如果我输入T等于599.9,则使用等式cp2而不是cp1来计算值Cp。 第3个温度范围也是如此。如果我输入T等于651.2,则用cp4而不是cp3计算Cp。 我不明白为什么。其余的工作正常。 该代码使用便携式Dev-C ++ 5.11进行编译。

由于

3 个答案:

答案 0 :(得分:6)

原因在于,计算机无法100%准确地代表每个数字。

如果你在阅读之后打印出你的T值,你实际上得到的是599.9000024,当然大于599.9并使用第3个陈述。

你可以使用double类型而不是具有更高精度的float来暂时解决这个问题。

答案 1 :(得分:5)

这可能是因为您正在转换浮点数和双精度数,从而引入舍入误差。根据经验,float1 == float2永远不可靠。双打同样如此。

答案 2 :(得分:4)

浮点不精确以及混合doublefloat类型有关。

599.9是双精度浮点字面值,Tfloat

对于T <= 599.9的某些值,比较T似乎行为不当。在评估表达式之前,T将被提升为double。它将保留由float引入的不精确性,因为C标准要求所有 float必须完全由{{ 1}}。

如果你要(i)使用double作为界限(这就是你写599.9f字面的方式),或者(ii)使用{{1},你会得到更多可解释的边界对于你的类型。

但是浮点不精确问题仍然存在:并非所有数字都可以在该方案中准确表示:599.9是IEEE754下的一个这样的数字。假设您的编译器使用IEEE754,则会出现您的特定问题,因为IEEE754 32位中的599.9大于599.9,大于599.9作为IEEE754 64位。