optimize math (#5287)
[betaflight.git] / src / main / common / gps_conversion.c
blob6d96365c1aeb6e572f8afb9e64202ae339019e9d
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <ctype.h>
21 #include <string.h>
23 #include "platform.h"
25 #ifdef USE_GPS
28 #define DIGIT_TO_VAL(_x) (_x - '0')
29 uint32_t GPS_coord_to_degrees(const char* coordinateString)
31 const char *fieldSeparator, *remainingString;
32 uint8_t degress = 0, minutes = 0;
33 uint16_t fractionalMinutes = 0;
34 uint8_t digitIndex;
36 // scan for decimal point or end of field
37 for (fieldSeparator = coordinateString; isdigit((unsigned char)*fieldSeparator); fieldSeparator++) {
38 if (fieldSeparator >= coordinateString + 15)
39 return 0; // stop potential fail
41 remainingString = coordinateString;
43 // convert degrees
44 while ((fieldSeparator - remainingString) > 2) {
45 if (degress)
46 degress *= 10;
47 degress += DIGIT_TO_VAL(*remainingString++);
49 // convert minutes
50 while (fieldSeparator > remainingString) {
51 if (minutes)
52 minutes *= 10;
53 minutes += DIGIT_TO_VAL(*remainingString++);
55 // convert fractional minutes
56 // expect up to four digits, result is in
57 // ten-thousandths of a minute
58 if (*fieldSeparator == '.') {
59 remainingString = fieldSeparator + 1;
60 for (digitIndex = 0; digitIndex < 4; digitIndex++) {
61 fractionalMinutes *= 10;
62 if (isdigit((unsigned char)*remainingString))
63 fractionalMinutes += *remainingString++ - '0';
66 return degress * 10000000UL + (minutes * 1000000UL + fractionalMinutes * 100UL) / 6;
68 #endif