From 13f27821b9af3b37c07f98244920dfe0ebf81918 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Mon, 6 May 2013 18:00:06 +0200 Subject: [PATCH] Completed GTX_multiple for negative values, issue #79 --- glm/gtx/multiple.inl | 80 +++++++++++++++++++++------------------ test/gtx/gtx_multiple.cpp | 57 ++++++++++++++++++++++++++-- 2 files changed, 97 insertions(+), 40 deletions(-) diff --git a/glm/gtx/multiple.inl b/glm/gtx/multiple.inl index bdf90280..80752446 100644 --- a/glm/gtx/multiple.inl +++ b/glm/gtx/multiple.inl @@ -41,14 +41,13 @@ namespace glm float Source = SourceH.toFloat(); float Multiple = MultipleH.toFloat(); - assert(float(0) <= Multiple); - - float SourceSign = sign(Source); - float SourceAbs = abs(Source); - - int Tmp = int(float(SourceAbs)) % int(Multiple); - return detail::half( - (Tmp ? SourceAbs + Multiple - float(Tmp) : SourceAbs) * SourceSign); + if (Source > float(0)) + { + float Tmp = Source - float(1); + return detail::half(Tmp + (Multiple - std::fmod(Tmp, Multiple))); + } + else + return detail::half(Source + std::fmod(-Source, Multiple)); } template <> @@ -58,13 +57,13 @@ namespace glm float const & Multiple ) { - assert(float(0) <= Multiple); - - float SourceSign = sign(Source); - float SourceAbs = abs(Source); - - int Tmp = int(SourceAbs) % int(Multiple); - return (Tmp ? SourceAbs + Multiple - float(Tmp) : SourceAbs) * SourceSign; + if (Source > float(0)) + { + float Tmp = Source - float(1); + return Tmp + (Multiple - std::fmod(Tmp, Multiple)); + } + else + return Source + std::fmod(-Source, Multiple); } template <> @@ -74,13 +73,13 @@ namespace glm double const & Multiple ) { - assert(double(0) <= Multiple); - - double SourceSign = sign(Source); - double SourceAbs = abs(Source); - - long Tmp = long(SourceAbs) % long(Multiple); - return (Tmp ? SourceAbs + Multiple - double(Tmp) : SourceAbs) * SourceSign; + if (Source > double(0)) + { + double Tmp = Source - double(1); + return Tmp + (Multiple - std::fmod(Tmp, Multiple)); + } + else + return Source + std::fmod(-Source, Multiple); } VECTORIZE_VEC_VEC(higherMultiple) @@ -95,11 +94,11 @@ namespace glm genType const & Multiple ) { - if (Source >= 0) + if (Source >= genType(0)) return Source - Source % Multiple; else { - genType Tmp = Source + 1; + genType Tmp = Source + genType(1); return Tmp - Tmp % Multiple - Multiple; } } @@ -114,10 +113,13 @@ namespace glm float Source = SourceH.toFloat(); float Multiple = MultipleH.toFloat(); - assert(float(0) <= Multiple); - - int Tmp = int(float(Source)) % int(float(Multiple)); - return detail::half(Tmp ? Source - float(Tmp) : Source); + if (Source >= float(0)) + return detail::half(Source - std::fmod(Source, Multiple)); + else + { + float Tmp = Source + float(1); + return detail::half(Tmp - std::fmod(Tmp, Multiple) - Multiple); + } } template <> @@ -127,10 +129,13 @@ namespace glm float const & Multiple ) { - assert(float(0) <= Multiple); - - int Tmp = int(Source) % int(Multiple); - return Tmp ? Source - float(Tmp) : Source; + if (Source >= float(0)) + return Source - std::fmod(Source, Multiple); + else + { + float Tmp = Source + float(1); + return Tmp - std::fmod(Tmp, Multiple) - Multiple; + } } template <> @@ -140,10 +145,13 @@ namespace glm double const & Multiple ) { - assert(double(0) <= Multiple); - - long Tmp = long(Source) % long(Multiple); - return Tmp ? Source - double(Tmp) : Source; + if (Source >= double(0)) + return Source - std::fmod(Source, Multiple); + else + { + double Tmp = Source + double(1); + return Tmp - std::fmod(Tmp, Multiple) - Multiple; + } } VECTORIZE_VEC_VEC(lowerMultiple) diff --git a/test/gtx/gtx_multiple.cpp b/test/gtx/gtx_multiple.cpp index ea1c4592..1e18bb44 100644 --- a/test/gtx/gtx_multiple.cpp +++ b/test/gtx/gtx_multiple.cpp @@ -10,7 +10,7 @@ #include #include -int test_higher() +int test_higher_int() { int Error(0); @@ -33,7 +33,7 @@ int test_higher() return Error; } -int test_Lower() +int test_Lower_int() { int Error(0); @@ -56,12 +56,61 @@ int test_Lower() return Error; } +int test_higher_double() +{ + int Error(0); + + Error += glm::higherMultiple(-9.0, 4.0) == -8.0 ? 0 : 1; + Error += glm::higherMultiple(-5.0, 4.0) == -4.0 ? 0 : 1; + Error += glm::higherMultiple(-4.0, 4.0) == -4.0 ? 0 : 1; + Error += glm::higherMultiple(-3.0, 4.0) == 0.0 ? 0 : 1; + Error += glm::higherMultiple(-2.0, 4.0) == 0.0 ? 0 : 1; + Error += glm::higherMultiple(-1.0, 4.0) == 0.0 ? 0 : 1; + Error += glm::higherMultiple(0.0, 4.0) == 0.0 ? 0 : 1; + Error += glm::higherMultiple(1.0, 4.0) == 4.0 ? 0 : 1; + Error += glm::higherMultiple(2.0, 4.0) == 4.0 ? 0 : 1; + Error += glm::higherMultiple(3.0, 4.0) == 4.0 ? 0 : 1; + Error += glm::higherMultiple(4.0, 4.0) == 4.0 ? 0 : 1; + Error += glm::higherMultiple(5.0, 4.0) == 8.0 ? 0 : 1; + Error += glm::higherMultiple(6.0, 4.0) == 8.0 ? 0 : 1; + Error += glm::higherMultiple(7.0, 4.0) == 8.0 ? 0 : 1; + Error += glm::higherMultiple(8.0, 4.0) == 8.0 ? 0 : 1; + Error += glm::higherMultiple(9.0, 4.0) == 12.0 ? 0 : 1; + + return Error; +} + +int test_Lower_double() +{ + int Error(0); + + Error += glm::lowerMultiple(-5.0, 4.0) == -8.0 ? 0 : 1; + Error += glm::lowerMultiple(-4.0, 4.0) == -4.0 ? 0 : 1; + Error += glm::lowerMultiple(-3.0, 4.0) == -4.0 ? 0 : 1; + Error += glm::lowerMultiple(-2.0, 4.0) == -4.0 ? 0 : 1; + Error += glm::lowerMultiple(-1.0, 4.0) == -4.0 ? 0 : 1; + Error += glm::lowerMultiple(0.0, 4.0) == 0.0 ? 0 : 1; + Error += glm::lowerMultiple(1.0, 4.0) == 0.0 ? 0 : 1; + Error += glm::lowerMultiple(2.0, 4.0) == 0.0 ? 0 : 1; + Error += glm::lowerMultiple(3.0, 4.0) == 0.0 ? 0 : 1; + Error += glm::lowerMultiple(4.0, 4.0) == 4.0 ? 0 : 1; + Error += glm::lowerMultiple(5.0, 4.0) == 4.0 ? 0 : 1; + Error += glm::lowerMultiple(6.0, 4.0) == 4.0 ? 0 : 1; + Error += glm::lowerMultiple(7.0, 4.0) == 4.0 ? 0 : 1; + Error += glm::lowerMultiple(8.0, 4.0) == 8.0 ? 0 : 1; + Error += glm::lowerMultiple(9.0, 4.0) == 8.0 ? 0 : 1; + + return Error; +} + int main() { int Error(0); - Error += test_higher(); - Error += test_Lower(); + Error += test_higher_int(); + Error += test_Lower_int(); + Error += test_higher_double(); + Error += test_Lower_double(); return Error; }