From 2d9e9863c216de9c9299a74726937fd97c0d0b2e Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Sat, 4 Jul 2015 19:29:50 +0200 Subject: [PATCH] refs #449 Implement SubdivisionConverters with less precision errors --- src/blackmisc/pq/measurementunit.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/blackmisc/pq/measurementunit.h b/src/blackmisc/pq/measurementunit.h index 0072a1ffd..66cfad8a9 100644 --- a/src/blackmisc/pq/measurementunit.h +++ b/src/blackmisc/pq/measurementunit.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace BlackMisc { @@ -117,9 +118,11 @@ namespace BlackMisc virtual double fromDefault(double factor) const override { using BlackMisc::Math::CMathUtils; - factor /= FactorPolicy::factor(); - double part2 = CMathUtils::fract(factor) * SubdivPolicy::subfactor(); - return CMathUtils::trunc(factor) + part2 / SubdivPolicy::fraction(); + double part1 = CMathUtils::trunc(factor / FactorPolicy::factor()); + double remaining = std::fmod(factor, FactorPolicy::factor()); + double part2 = CMathUtils::trunc(remaining / SubdivPolicy::subfactor()); + remaining = std::fmod(remaining, SubdivPolicy::subfactor()); + return part1 + (part2 + remaining) / SubdivPolicy::fraction(); } }; @@ -142,10 +145,13 @@ namespace BlackMisc virtual double fromDefault(double factor) const override { using BlackMisc::Math::CMathUtils; - factor /= FactorPolicy::factor(); - double part2 = CMathUtils::fract(factor) * SubdivPolicy::subfactor(); - double part3 = CMathUtils::fract(part2) * SubdivPolicy::subfactor(); - return CMathUtils::trunc(factor) + (CMathUtils::trunc(part2) + part3 / SubdivPolicy::fraction()) / SubdivPolicy::fraction(); + double part1 = CMathUtils::trunc(factor / FactorPolicy::factor()); + double remaining = std::fmod(factor, FactorPolicy::factor()); + double part2 = CMathUtils::trunc(remaining / SubdivPolicy::subfactor()); + remaining = std::fmod(remaining, SubdivPolicy::subfactor()); + double part3 = CMathUtils::trunc(remaining / SubdivPolicy::subfactor()); + remaining = std::fmod(remaining, SubdivPolicy::subfactor()); + return part1 + part2 / SubdivPolicy::fraction() + (part3 + remaining) / (SubdivPolicy::fraction() * SubdivPolicy::fraction()); } };