2017-09-25 53 views
1

这是一个较大的程序的一部分,但我有被生成的计算值的表的开始和结束在一个麻烦的唯一部分递增最终值初始和最终价值。出于某种原因,在给定的增量值是0.2,它工作完全正常,但是当给定的值是0.05,它不显示的最终值。试图从创建计算值的表和初始由一个给定数目

这里是我对那部分代码:

for (volume = initialVol; volume <= finalVol; volume += volumeIncrement) { 

    pressure = pressure_cal(gasNumber, temperature, volume, gasQuantity); 

    printf("%.3lf\t\t\t %.4lf\n", volume, pressure); 
} 

另外,如果我改变for条件volume <= finalVol + volumeIncrement,它将为0.05工作,但不0.2

编辑:我想我还要补充一点,如果我取代比方说,在USERDEF功能压力= 1;显示的音量值不受任何影响。

+0

和该功能?:*** pressure_cal(gasNumber,温度,体积,gasQuantity); *** –

+0

它是一个函数来用给定的音量值计算压力值。它应该按volumeIncrement(0.2或0.05)递增并计算从初始量到最终量的所有可能的压力值。 –

+0

也许是功能不正常的一个.... –

回答

1

问题来自浮点计算中的舍入误差,该计算处理的格式不能精确地表示为doublefloat格式。你的0.20.05增量的2负幂的整数倍,所以在IEEE二进制格式表示四舍五入:

  • 如果volumeIncrement四舍五入到一个较低的值,最终的测试会取得成功,因为volume将是一个小于finalVol。这是0.2;
  • 反之,如果volumeIncrement四舍五入到一个较大的值,最终测试将失败,因为volume将超过finalVol。这是0.05发生的情况。

有多种方式来避免这个问题:

  • 您可以在较小的值增加volume,以确保最终成功的比较:volume <= finalVol + volumeIncrement/2将是一个简单的方法来实现这一目标。
  • 您可以使用整数算术,只有转化为浮点进行计算,而不是枚举。例如,您会使用整数毫升而不是分数升,并使用205的增量。
  • 您可以指定步数而不是增量。

下面是最后一种方法修改后的代码:

int steps = 100; 
for (int step = 0; step <= steps; step++) { 
    double volume = initialVol + (finalVol - initialVol) * step/steps; 
    double pressure = pressure_cal(gasNumber, temperature, volume, gasQuantity); 
    printf("%.3f\t\t\t %.4f\n", volume, pressure); 
} 
相关问题