2

如何提高以下准确性(精度)?

struct Degree_Minutes { signed int degrees; signed int minutes; double seconds; };
Degree_Minutes geo_dec_to_deg (double dec)
{
    Degree_Minutes degrees_minutes;
    signed int degrees, minutes;
    double remainder, temp, seconds;

    remainder = fmod(dec, 1);
    degrees_minutes.degrees = dec - remainder;
    temp = remainder*60;
    remainder = fmod(temp,1);
    degrees_minutes.minutes = temp-remainder;
    degrees_minutes.seconds = remainder*60;

    return degrees_minutes;
}

    double geo_deg_to_dec (Degree_Minutes degrees)
{
    double decimal = degrees.degrees + (degrees.minutes/60) + (degrees.seconds/60);
    return decimal;
}

int main(int argc, char **argv)
{
    Degree_Minutes deg;
    double decimal = 38.898556;

    deg = geo_dec_to_deg(decimal);
    cout << "Results of geo_dec_to_deg function: \n" << decimal << " was converted to " << deg.degrees << " degrees, " << deg.minutes << " minutes, " << deg.seconds << " seconds.\n";
    decimal = geo_deg_to_dec(deg);
    cout << "Results of geo_dec_to_deg function: \n" << deg.degrees << " degrees, " << deg.minutes << " minutes, " << deg.seconds << " seconds was converted to " << decimal << "\n";

    return EXIT_SUCCESS;
}

编辑:忘记添加这里有一个结构:

struct Degree_Minutes { signed int degrees; signed int minutes; double seconds; };

当您从十进制转换为度/分/秒,然后再转换回十进制时,您会得到 38.9134,而原始值为 38.898556。

4

3 回答 3

6

由于意外的整数除法,您遇到了舍入/截断错误。要获得正确的双精度,您需要隐式转换degrees.minutesand degrees.secondsdouble如下所示:

double decimal = degrees.degrees + (degrees.minutes/60.0) + (degrees.seconds/3600.0);

注意秒字段中的60->60.0和 60 到 3600 的更正。

于 2012-10-23T20:07:56.573 回答
2

有两个问题。

首先,结构的minutes成员Degree_Minutes被声明为整数类型,因此degrees.minutes/60将整数除以整数,这会产生截断的整数结果。将其更改为degrees.minutes/60.产生浮点结果。

degrees.seconds/60是不正确。这应该degrees.seconds/3600degrees.seconds/60应该添加到degrees.minutes,然后将总和除以60。

于 2012-10-23T20:16:33.713 回答
1
#include <stdlib.h>
#include <iostream>
#include <math.h>

using namespace std;

struct Degree_Minutes { signed int degrees; signed int minutes; double seconds; };

Degree_Minutes geo_dec_to_deg (double dec)
{
    Degree_Minutes degrees_minutes;
    signed int degrees, minutes;
    double remainder, temp, seconds;

    remainder = fmod(dec, 1);
    degrees_minutes.degrees = dec - remainder;
    temp = remainder*60.0;
    remainder = fmod(temp,1);
    degrees_minutes.minutes = temp-remainder;
    degrees_minutes.seconds = remainder*60.0;

    return degrees_minutes;
}

double geo_deg_to_dec (Degree_Minutes degrees)
{
    double decimal = degrees.degrees + (degrees.minutes/60.0) + (degrees.seconds/60.0/60.0);
    return decimal;
}

int main(int argc, char **argv)
{
    Degree_Minutes deg;
    double decimal = 38.898556;

    deg = geo_dec_to_deg(decimal);
    cout << "Results of geo_dec_to_deg function: \n" << decimal << " was converted to " << deg.degrees << " degrees, " << deg.minutes << " minutes, " << deg.seconds << " seconds.\n";
    cout << "This should be: 38deg 53' 54.801\"" << endl;
    cout << endl;
    decimal = geo_deg_to_dec(deg);
    cout << "Results of geo_dec_to_deg function: \n" << deg.degrees << " degrees, " << deg.minutes << " minutes, " << deg.seconds << " seconds was converted to " << decimal << "\n";
    cout << "This should be: 38.898556" << endl;

    return EXIT_SUCCESS;
}

你几乎拥有它。您需要通过明确指定小数来强制双除(如另一个答案中所示),但您还需要将秒数除以 60 两次。在实践中,我可能会将其更改为degrees.seconds/3600,但我保留它是为了说明。

于 2012-10-23T20:16:05.260 回答