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.