From 16f4e083950d4e74fa24da275b4902c2b4fd376d Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Mon, 10 Jun 2013 22:38:33 +0000 Subject: [PATCH] attempt to speed up float truncation and add some unit tests --- .../shared_lib/include/graphics/math_util.h | 46 +++++++++++++ source/tests/CMakeLists.txt | 1 + .../shared_lib/graphics/math_util_test.cpp | 68 +++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 source/tests/shared_lib/graphics/math_util_test.cpp diff --git a/source/shared_lib/include/graphics/math_util.h b/source/shared_lib/include/graphics/math_util.h index 6ca74d90e..59ab4476c 100644 --- a/source/shared_lib/include/graphics/math_util.h +++ b/source/shared_lib/include/graphics/math_util.h @@ -14,9 +14,11 @@ #include "math_wrapper.h" #include "vec.h" +#include "data_types.h" #include "leak_dumper.h" using namespace std; +using namespace Shared::Platform; namespace Shared{ namespace Graphics{ @@ -276,8 +278,46 @@ inline T radToDeg(T rad){ return (rad*360)/(2*pi); } +// ==================================================================================================================== +// ==================================================================================================================== +// Inline implementation +// ==================================================================================================================== +// ==================================================================================================================== +#if _xs_BigEndian_ + #define _xs_iexp_ 0 + #define _xs_iman_ 1 +#else + #define _xs_iexp_ 1 //intel is little endian + #define _xs_iman_ 0 +#endif //BigEndian_ + +//#define finline __forceinline +#define finline inline + +#ifndef _xs_DEFAULT_CONVERSION +#define _xs_DEFAULT_CONVERSION 0 +#endif + +//typedef long int32; +typedef double real64; +const real64 _xs_doublemagic = real64 (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor + +finline int32 xs_CRoundToInt(real64 val, real64 dmr = _xs_doublemagic) { +#if _xs_DEFAULT_CONVERSION==0 + val = val + dmr; + return ((int32*)&val)[_xs_iman_]; + //return 0; +#else + return int32(floor(val+.5)); +#endif +} + + + template inline T truncateDecimal(const T &value, int precision=6) { + +/* int iSigned = value >= 0 ? 1: -1; #ifdef USE_STREFLOP @@ -288,6 +328,12 @@ inline T truncateDecimal(const T &value, int precision=6) { T result = (((double)uiTemp) / pow((T)10,precision) * iSigned); #endif return result; +*/ + + T precNum = pow(10, precision); + T result = xs_CRoundToInt(value * precNum); + result /= precNum; + return result; } diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 2ad2a988f..7ed3797a7 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -26,6 +26,7 @@ IF(BUILD_MEGAGLEST_TESTS) SET(DIRS_WITH_SRC ./ + shared_lib/graphics shared_lib/xml) SET(MG_INCLUDES_ROOT "./") diff --git a/source/tests/shared_lib/graphics/math_util_test.cpp b/source/tests/shared_lib/graphics/math_util_test.cpp new file mode 100644 index 000000000..f22dd6eeb --- /dev/null +++ b/source/tests/shared_lib/graphics/math_util_test.cpp @@ -0,0 +1,68 @@ +// ============================================================== +// This file is part of MegaGlest Unit Tests (www.megaglest.org) +// +// Copyright (C) 2013 Mark Vejvoda +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#include +#include +#include "math_util.h" + +#ifdef WIN32 +#include +#else +#include +#endif + +using namespace Shared::Graphics; + +// +// Tests for XmlIo +// +class MathUtilTest : public CppUnit::TestFixture { + // Register the suite of tests for this fixture + CPPUNIT_TEST_SUITE( MathUtilTest ); + + CPPUNIT_TEST( test_RoundFloat ); + + CPPUNIT_TEST_SUITE_END(); + // End of Fixture registration + +public: + + void test_RoundFloat() { + float value1 = truncateDecimal(1.123456f, 6); + CPPUNIT_ASSERT_EQUAL( 1.123456f, value1 ); + + value1 = truncateDecimal(1.123456f, 5); + CPPUNIT_ASSERT_EQUAL( 1.12346f, value1 ); + + value1 = truncateDecimal(1.123456f, 4); + CPPUNIT_ASSERT_EQUAL( 1.1235f, value1 ); + + value1 = truncateDecimal(1.123456f, 3); + CPPUNIT_ASSERT_EQUAL( 1.123f, value1 ); + + value1 = truncateDecimal(1.123456f, 2); + CPPUNIT_ASSERT_EQUAL( 1.12f, value1 ); + + value1 = truncateDecimal(1.123456f, 1); + CPPUNIT_ASSERT_EQUAL( 1.1f, value1 ); + + int32 value2 = xs_CRoundToInt(1.123456f); + CPPUNIT_ASSERT_EQUAL( (int32)1, value2 ); + + value2 = xs_CRoundToInt(1.523456f); + CPPUNIT_ASSERT_EQUAL( (int32)2, value2 ); + } +}; + + +// Test Suite Registrations +CPPUNIT_TEST_SUITE_REGISTRATION( MathUtilTest ); +//