- Add function equalsByUlp to test for spacing between floating point numbers.
- Allow difference of 1 ULP in fast_atof tests (as that is still correct). Note that this only fixes part of the fast_atof test, the whole tests still fails on 64-bit because test_strtol still fails (that looks more like a real bug). git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4179 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
366c0e48b5
commit
833ad991dd
|
@ -1,5 +1,7 @@
|
|||
Changes in 1.8 (??.??.2011)
|
||||
|
||||
- new function equalsByUlp to test for spacing between floating point numbers.
|
||||
|
||||
- speedup for collada writing.
|
||||
|
||||
- speedup for xml-writing.
|
||||
|
|
|
@ -303,8 +303,7 @@ inline f32 strtof10(const char* in, const char** out = 0)
|
|||
*/
|
||||
inline const char* fast_atof_move(const char* in, f32& result)
|
||||
{
|
||||
// Please run this regression test when making any modifications to this function:
|
||||
// https://sourceforge.net/tracker/download.php?group_id=74339&atid=540676&file_id=298968&aid=1865300
|
||||
// Please run the regression test when making any modifications to this function.
|
||||
|
||||
result = 0.f;
|
||||
if (!in)
|
||||
|
|
|
@ -188,6 +188,36 @@ namespace core
|
|||
{
|
||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
||||
}
|
||||
|
||||
//! We compare the difference in ULP's (spacing between floating-point numbers, aka ULP=1 means there exists no float between).
|
||||
//\result true when numbers have a ULP <= maxUlpDiff AND have the same sign.
|
||||
inline bool equalsByUlp(f32 a, f32 b, int maxUlpDiff)
|
||||
{
|
||||
// Based on the ideas from Bruce Dawson on
|
||||
// http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/
|
||||
// When floats are interpreted as integers the two nearest possible float numbers differ just
|
||||
// by one integer number. Also works the other way round, an integer of 1 interpreted as float
|
||||
// is for example the smallest possible float number.
|
||||
int ia = *reinterpret_cast<int*>(&a);
|
||||
int ib = *reinterpret_cast<int*>(&b);
|
||||
|
||||
// Different signs, we could maybe get difference to 0, but so close to 0 using epsilons is better.
|
||||
if ( (ia >> 31 != 0) != (ib >> 31 != 0) )
|
||||
{
|
||||
// Check for equality to make sure +0==-0
|
||||
if (a == b)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the difference in ULPs.
|
||||
int ulpsDiff = abs_(ia - ib);
|
||||
if (ulpsDiff <= maxUlpDiff)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//! returns if a equals b, not using any rounding tolerance
|
||||
inline bool equals(const s32 a, const s32 b)
|
||||
|
|
|
@ -90,7 +90,9 @@ static bool testCalculation_atof(const char * valueString)
|
|||
logTestString("\n String '%s'\n New fast %.40f\n Old fast %.40f\n atof %.40f\n",
|
||||
valueString, newFastValue, oldFastValue, atofValue);
|
||||
|
||||
bool accurate = fabs(newFastValue - atofValue) <= fabs(oldFastValue - atofValue);
|
||||
const f32 diffNew = fabs(newFastValue - atofValue) ;
|
||||
const f32 diffOld = fabs(newFastValue - atofValue) ;
|
||||
bool accurate = diffNew <= diffOld || equalsByUlp(diffNew, diffOld, 1);
|
||||
|
||||
if(!accurate)
|
||||
logTestString("*** ERROR - less accurate than old method ***\n\n");
|
||||
|
@ -275,5 +277,8 @@ bool test_strtol(void)
|
|||
|
||||
bool fast_atof(void)
|
||||
{
|
||||
return test_fast_atof() && test_strtol();
|
||||
bool ok = true;
|
||||
ok &= test_fast_atof() ;
|
||||
ok &= test_strtol();
|
||||
return ok;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Tests finished. 1 test of 1 passed.
|
||||
Compiled as DEBUG
|
||||
Test suite pass at GMT Sun Jun 3 18:56:35 2012
|
||||
Test suite pass at GMT Sun Jun 3 20:56:51 2012
|
||||
|
||||
|
|
Loading…
Reference in New Issue