Use sprintf to decompose the degrees, minutes, and seconds

Instead of repeatedly multiplying by 100, which can cause
epsilon errors to grow to too significant magnitudes.
This commit is contained in:
Mat Sutcliffe
2020-12-08 21:02:19 +00:00
parent 50eebb799d
commit 40362c1f4a
2 changed files with 15 additions and 7 deletions

View File

@@ -73,13 +73,12 @@ namespace BlackMisc
dms *= -1.0;
}
values.deg = CMathUtils::trunc(dms);
dms = CMathUtils::fract(dms) * 100;
values.min = CMathUtils::trunc(dms);
dms = CMathUtils::fract(dms) * 100;
values.sec = CMathUtils::trunc(dms);
dms = CMathUtils::fract(dms);
values.fractionalSec = CMathUtils::round(dms, 6);
char chars[16];
std::sprintf(chars, "%014.10f", dms); // 000.0000000000
values.deg = stringToInt(chars, chars + 3);
values.min = stringToInt(chars + 4, chars + 6);
values.sec = stringToInt(chars + 6, chars + 8);
values.fractionalSec = stringToInt(chars + 8, chars + 14) / 1000000.0;
return values;
}

View File

@@ -234,6 +234,15 @@ namespace BlackMisc
//! Convert string to bool
BLACKMISC_EXPORT bool stringToBool(const QString &boolString);
//! Convert string (begin and end iterators of char) to int
template <typename It>
int stringToInt(It begin, It end)
{
int result = 0;
std::for_each(begin, end, [&result](char c) { Q_ASSERT(is09(c)); result *= 10; result += (c - '0'); });
return result;
}
//! Fuzzy compare for short strings (like ICAO designators)
//! \return int 0..100 (100 is perfect match)
BLACKMISC_EXPORT int fuzzyShortStringComparision(const QString &str1, const QString &str2, Qt::CaseSensitivity cs = Qt::CaseSensitive);