在C#和 JavaScript中计算一个复杂的方程
在一个气象程序(CumulusMX)中,湿球温度的数值是这样计算的:
public static double CalculateWetBulbC(double tempC, double dewPointC, double pressureMb)
{
double svpDP = SaturationVapourPressure1980(dewPointC);
return (((0.00066 * pressureMb) * tempC) + ((4098 * svpDP) / (Sqr(dewPointC + 237.7)) * dewPointC)) / ((0.00066 * pressureMb) + (4098 * svpDP) / (Sqr(dewPointC + 237.7)));
}
其中 svpDP 表示:
public static double SaturationVapourPressure1980(double tempC)
{
return 6.112 * Math.Exp(17.67 * tempC / (tempC + 243.5));
}
而 Sqr(a) 表示参数的平方(a*a)。
在JavaScript中,这个数值也以相同的方式计算为:
(0.00066 * Pressure[i][1] * Temperature[i][1] + 4098 * 6.112 * Math.exp(17.67 * Temperature[i][1] / (243.5 + Temperature[i][1]))
/ Math.pow((Dewpoint[i][1] + 237.7), 2) * Dewpoint[i][1]) / (0.00066 * Pressure[i][1] + 4098 * 6.112
* Math.exp(17.67 * Temperature[i][1] / (243.5 + Temperature[i][1])) / Math.pow((Dewpoint[i][1] + 237.7), 2))
请注意,计算中的所有元素都合并进了一个方程。
[i][1] 的索引指向一个JSON数组中,代表过去三天中某一分钟的数值,因此可以对过去三天的每一分钟计算湿球温度。
在过去三天的每一分钟,也给出了C#的计算结果。
你可以在这里查看所有这些数值的图表:
你会发现这些数值存在差异:
- wetbulb_1minwetbulb 来自CumulusMX的 C#计算,频率为每分钟一次
- Natte Bol Temperatuur 来自JavaScript的计算,同样按每分钟的频率进行
在C#与 JavaScript方程之间的差异中没有发现错误。
这个差异可能来自哪里?
我在考虑C#运行时或JavaScript实际处理这类复杂方程的方式,但我想了解两者计算之间差异的机理。
这两组方程的数据是完全相同的,参见这里:
- 基础数据在tempdata和 pressdata中,这些数据在C#中按分钟使用,随后在JavaScript中使用(因此有索引)
- C#的结果存放在 'customlogsRecentdata.json'
- 开头的JSON可能有一两分钟的差异,但数据都是你想要的那一分钟
解决方案
你的
(((0.00066 * pressureMb) * tempC) +
((4098 * svpDP) / (Sqr(dewPointC + 237.7)) * dewPointC)) /
((0.00066 * pressureMb) + (4098 * svpDP) / (Sqr(dewPointC + 237.7)))
在C#中实际上计算出
(((0.00066 * pressureMb) * tempC) +
((4098 * 6.112 * Math.Exp(17.67 * tempC / (tempC + 243.5))) /
(Sqr(dewPointC + 237.7)) * dewPointC)) /
((0.00066 * pressureMb) +
(4098 * 6.112 * Math.Exp(17.67 * tempC / (tempC + 243.5))) /
(Sqr(dewPointC + 237.7)))
在Javascript中你得到的是
(0.00066 * Pressure[i][1] * Temperature[i][1] +
4098 * 6.112 *
Math.exp(17.67 * Temperature[i][1] / (243.5 + Temperature[i][1])) /
Math.pow((Dewpoint[i][1] + 237.7), 2) * Dewpoint[i][1]) /
(0.00066 * Pressure[i][1] +
4098 * 6.112 *
Math.exp(17.67 * Temperature[i][1] / (243.5 + Temperature[i][1])) /
Math.pow((Dewpoint[i][1] + 237.7), 2))
(我已对代码进行了格式化以便更易读)
在不知道以下条件时,这两者在此处不可直接比较:
- pressureMb是否与Pressure[i][1完全一致
- tempC是否与Temperature[i][1完全一致
- dewPointC是否与Dewpoint[i][1完全一致
但若假设这些值是精确匹配,那么公式看起来相似。以下是我的建议:
- 记录数值不同的时候,C#与 Javascript的确切数值;如果存在差异,那就是你要找的原因
- 逐项监控方程中各部分的确切数值,以便发现差异
- 哪一方是正确的,如有错误(C#还是Javascript)
我也不确定 tempC 的一般含义,因为在你的图中它是“Y”顶点,而你的计算把它当作给定值使用;从图片看,它似乎是输出,而在公式中似乎是输入。如果是这样,那么你就会在 tempC 和 Temperature[i][1] 之间看到差异。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。
