我编写了一个程序来获取两个gps-Position之间的角度。它在C#中可以正常工作,但在C中则不能。问题出在哪里?

这是C#中的代码

double lat1 = GetRAD(pos1.Latitude);
double lat2 = GetRAD(pos2.Latitude);
double long1 = GetRAD(pos1.Longitude);
double long2 = GetRAD(pos2.Longitude);

double angleAtCentre = Math.Acos(Math.Sin(lat1) * Math.Sin(lat2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(long2 - long1));

double retVal = Math.Acos((Math.Sin(lat2) - Math.Sin(lat1) * Math.Cos(angleAtCentre)) / (Math.Cos(lat1) * Math.Sin(angleAtCentre)));
retVal = retVal * 180.0 / Math.PI;
if (long1 > long2)
{
    retVal = retVal * (-1);
}

return retVal;


这是C中的代码

double lat1 = GetRAD(pos1.latitude);
double lat2 = GetRAD(pos2.latitude);
double long1 = GetRAD(pos1.longitude);
double long2 = GetRAD(pos2.longitude);

double angleAtCentre = acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(long2 - long1));

double retVal = acos((sin(lat2) - sin(lat1) * cos(angleAtCentre)) / (cos(lat1) * sin(angleAtCentre)));
retVal = GetDEG(retVal);
if(long1 > long2)
    {
    retVal = retVal * (-1);
}
return retVal;


我尝试了以下坐标:Pos1(47.0998194N,9.8605694E),Pos2(47.1004972N,9.8600639E)
在C#中正确的结果是-26.9度,在C中我得到的像是-88

最佳答案

您为问题标题:


  使用Sin和Cos在C和C#中的不同结果


但是,您可以放心,两种语言的标准库函数都能正确执行三角函数。问题代码中的表达式在两个版本中相同。因此,差异行为必须来自度/弧度转换函数,您已省略了该函数的代码。

您的两个值-88-26.9的比率为3.27,非常接近π。所以我的猜测是您的C实现GetDEG是不正确的。我怀疑您是这样写的:

deg = rad * 180.0;


但是它必须是:

deg = rad * 180.0 / pi;


如果包含math.h,则可以将M_PI用于π。或者,如果您的math.h没有定义M_PI,则可以自己定义。您可以编写度/弧度转换函数,如下所示:

double rad2deg(double rad)
{
    return rad * 180.0 / M_PI;
}

double deg2rad(double deg)
{
    return deg * M_PI / 180.0;
}


最后的评论是,通常通过使用-运算符的一元形式而不是乘法来对数字求反:

retVal = -retVal;


这比您的代码读起来清晰得多,并且匹配表达式的数学编写方式。

一个完整的程序演示了这一点:

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

#define M_PI 3.1415926535897932384626433832795

double rad2deg(double rad)
{
    return rad * 180.0 / M_PI;
}

double deg2rad(double deg)
{
    return deg * M_PI / 180.0;
}

double angleBetween(double lat1, double long1, double lat2, double long2)
{
    double angleAtCentre = acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(long2 - long1));
    double retVal = acos((sin(lat2) - sin(lat1) * cos(angleAtCentre)) / (cos(lat1) * sin(angleAtCentre)));
    return long1 > long2 ? -retVal : retVal;
}

int main(void)
{
    double angle = angleBetween(
        deg2rad(47.0998194), deg2rad(9.8605694),
        deg2rad(47.1004972), deg2rad(9.8600639)
    );
    printf("%f\n", rad2deg(angle));
}


输出量

-26.915686


我建议您在系统上运行该程序,以便亲自查看它是否提供了所需的输出。



更新资料

您在注释中声称,上面的程序在您的系统上产生输出-92。如果真是这样,那么问题确实与您的系统有关。虽然,您的主张对我来说似乎有点牵强,但是如果您的系统确实输出了该值,那么它将被破坏。

10-06 15:03