Как повысить точность кода

Как я могу улучшить точность (точность) следующего?

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.

2

Решение

Вы столкнулись с ошибкой округления / усечения из-за непреднамеренного целочисленного деления. Чтобы получить правильную двойную точность, вам нужно неявно конвертировать degrees.minutes а также degrees.seconds в double, как это:

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

Обратите внимание 60 -> 60.0 и исправление от 60 до 3600 в поле секунд.

6

Другие решения

Есть две проблемы.

Во-первых, minutes член Degree_Minutes структура объявлена ​​как целочисленный тип, поэтому degrees.minutes/60 делит и целое число на целое число, которое приводит к усеченному целочисленному результату. Меняя это на degrees.minutes/60. дает результат с плавающей точкой.

Во-вторых, degrees.seconds/60 это неверно. Либо это должно быть degrees.seconds/3600 или же degrees.seconds/60 следует добавить к градусам. минутам, а затем к 60.

2

#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, но я оставил это как для иллюстрации.

1
По вопросам рекламы [email protected]