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。

+0

哦,顺便说一句我忘记注意结构:struct Degree_Minutes {signed int degrees;签名int分钟;双秒; }; –

+0

请编辑帖子以包含此新信息。 –

+0

没有必要包含Degree_Minutes声明,因为它可以从所提供的信息中推导出来。 (如果'minutes'已被声明为浮点数或'seconds'已被声明为整数,则将获得不同的结果。) –

回答

6

由于意外的整数除法,您正在经历舍入/截断错误。为了得到你需要隐式转换degrees.minutesdegrees.secondsdouble,像这样适当的双精度:

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

60 - >60.0和60秒字段校正至3600。

+2

有一个编译器选项可以警告你这样的错误,如果我没有弄错,gcc和clang的''WConversion''。 “墙”更好。 :-) – Florian

+2

有3600秒的学位。 –

+0

啊,我明白了......因为我使用了signed int(不知道为什么我为分钟签名)。所以,通过使用双重它应该将其转换.... 好吧,试过这个,但是,它现在是从原来的进一步。一旦转换回来,它变成39.7967与38.8985 –

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,但我已将其留在原地进行说明。

2

有两个问题。

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

二,degrees.seconds/60不正确。或者这应该是degrees.seconds/3600degrees.seconds/60应该加上degree.minutes和总和,然后除以60.