bugfix for float rounding segfault

This commit is contained in:
Mark Vejvoda
2013-06-11 01:23:04 +00:00
parent 473e79c356
commit 267dc7534f
2 changed files with 64 additions and 40 deletions

View File

@@ -283,36 +283,34 @@ inline T radToDeg(T rad){
// Inline implementation // Inline implementation
// ==================================================================================================================== // ====================================================================================================================
// ==================================================================================================================== // ====================================================================================================================
#if _xs_BigEndian_ //#if _xs_BigEndian_
#define _xs_iexp_ 0 // #define _xs_iexp_ 0
#define _xs_iman_ 1 // #define _xs_iman_ 1
#else //#else
#define _xs_iexp_ 1 //intel is little endian // #define _xs_iexp_ 1 //intel is little endian
#define _xs_iman_ 0 // #define _xs_iman_ 0
#endif //BigEndian_ //#endif //BigEndian_
//
//#define finline __forceinline ////#define finline __forceinline
#define finline inline //#define finline inline
//
#ifndef _xs_DEFAULT_CONVERSION //#ifndef _xs_DEFAULT_CONVERSION
#define _xs_DEFAULT_CONVERSION 0 //#define _xs_DEFAULT_CONVERSION 0
#endif //#endif
//
//typedef long int32; ////typedef long int32;
typedef double real64; //typedef double real64;
const real64 _xs_doublemagic = real64 (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor //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) { //finline int32 xs_CRoundToInt(real64 val, real64 dmr = _xs_doublemagic) {
#if _xs_DEFAULT_CONVERSION==0 //#if _xs_DEFAULT_CONVERSION==0
val = val + dmr; // val = val + dmr;
return ((int32*)&val)[_xs_iman_]; // return ((int32*)&val)[_xs_iman_];
//return 0; // //return 0;
#else //#else
return int32(floor(val+.5)); // return int32(floor(val+.5));
#endif //#endif
} //}
template<typename T> template<typename T>
inline T truncateDecimal(const T &value, int precision=6) { inline T truncateDecimal(const T &value, int precision=6) {
@@ -330,9 +328,35 @@ inline T truncateDecimal(const T &value, int precision=6) {
return result; return result;
*/ */
T precNum = std::pow((T)10, (T)precision); T precNum = 0;
T result = xs_CRoundToInt(value * precNum); if(precision == 0) {
result /= precNum; precNum = 1;
}
else if(precision == 1) {
precNum = 10;
}
else if(precision == 2) {
precNum = 100;
}
else if(precision == 3) {
precNum = 1000;
}
else if(precision == 4) {
precNum = 10000;
}
else if(precision == 5) {
precNum = 100000;
}
else if(precision == 6) {
precNum = 1000000;
}
else {
precNum = std::pow((T)10,(T)precision);
}
int64 resultInt = (T)value * (T)precNum;
T result = (long double)resultInt / precNum;
return result; return result;
} }

View File

@@ -40,10 +40,10 @@ public:
CPPUNIT_ASSERT_EQUAL( 1.123456f, value1 ); CPPUNIT_ASSERT_EQUAL( 1.123456f, value1 );
value1 = truncateDecimal<float>(1.123456f, 5); value1 = truncateDecimal<float>(1.123456f, 5);
CPPUNIT_ASSERT_EQUAL( 1.12346f, value1 ); CPPUNIT_ASSERT_EQUAL( 1.12345f, value1 );
value1 = truncateDecimal<float>(1.123456f, 4); value1 = truncateDecimal<float>(1.123456f, 4);
CPPUNIT_ASSERT_EQUAL( 1.1235f, value1 ); CPPUNIT_ASSERT_EQUAL( 1.1234f, value1 );
value1 = truncateDecimal<float>(1.123456f, 3); value1 = truncateDecimal<float>(1.123456f, 3);
CPPUNIT_ASSERT_EQUAL( 1.123f, value1 ); CPPUNIT_ASSERT_EQUAL( 1.123f, value1 );
@@ -54,11 +54,11 @@ public:
value1 = truncateDecimal<float>(1.123456f, 1); value1 = truncateDecimal<float>(1.123456f, 1);
CPPUNIT_ASSERT_EQUAL( 1.1f, value1 ); CPPUNIT_ASSERT_EQUAL( 1.1f, value1 );
int32 value2 = xs_CRoundToInt(1.123456f); // int32 value2 = xs_CRoundToInt(1.123456f);
CPPUNIT_ASSERT_EQUAL( (int32)1, value2 ); // CPPUNIT_ASSERT_EQUAL( (int32)1, value2 );
//
value2 = xs_CRoundToInt(1.523456f); // value2 = xs_CRoundToInt(1.523456f);
CPPUNIT_ASSERT_EQUAL( (int32)2, value2 ); // CPPUNIT_ASSERT_EQUAL( (int32)2, value2 );
} }
}; };