我几乎没有编程经验,但我必须编写一个简单的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进行编译。
由于
答案 0 :(得分:6)
原因在于,计算机无法100%准确地代表每个数字。
如果你在阅读之后打印出你的T值,你实际上得到的是599.9000024,当然大于599.9并使用第3个陈述。
你可以使用double类型而不是具有更高精度的float来暂时解决这个问题。
答案 1 :(得分:5)
这可能是因为您正在转换浮点数和双精度数,从而引入舍入误差。根据经验,float1 == float2
永远不可靠。双打同样如此。
答案 2 :(得分:4)
与浮点不精确以及混合double
和float
类型有关。
599.9
是双精度浮点字面值,T
是float
。
对于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位。