From 40362c1f4a1b14cfe7ebc2b42496fc4dc24310da Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Tue, 8 Dec 2020 21:02:19 +0000 Subject: [PATCH] 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. --- src/blackmisc/pq/angle.cpp | 13 ++++++------- src/blackmisc/stringutils.h | 9 +++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/blackmisc/pq/angle.cpp b/src/blackmisc/pq/angle.cpp index 8fbf9ed03..0c6247a84 100644 --- a/src/blackmisc/pq/angle.cpp +++ b/src/blackmisc/pq/angle.cpp @@ -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; } diff --git a/src/blackmisc/stringutils.h b/src/blackmisc/stringutils.h index 2a884a600..59c4907e8 100644 --- a/src/blackmisc/stringutils.h +++ b/src/blackmisc/stringutils.h @@ -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 + 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);