C和C#与Sin和Cos的结果不同

时间:2014-06-24 09:18:38

标签: c# c sin cos

我写了一个程序来获得两个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

的结果

2 个答案:

答案 0 :(得分:0)

你标题是你的问题:

  

C和C#与Sin和Cos的结果不同

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

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

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。如果确实如此,那么问题确实与您的系统有关。虽然,你的说法对我来说似乎有点牵强,但如果你的系统确实输出了这个值,那么它就会被打破。

答案 1 :(得分:-1)

您的子程序错了。我的代码:

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

int main(void)
{
    double lat1 = 47.0998194 * 0.0174532925;
    double lat2 = 47.1004972 * 0.0174532925;
    double long1 = 9.8605694 * 0.0174532925;
    double long2 = 9.8600639 * 0.0174532925;

    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 = retVal * 180.0 / 3.1415;
    if(long1 > long2){
        retVal = retVal * (-1);
    }

    printf("value: %f\n", retVal);
}

0.0174532925乘数用于将度数转换为弧度。输出:

value: -26.916409

瞧..

下次发布问题时,请确保包含子例程以及pos1pos2的结构。还假设您包含math.h