123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- // Copyright (C) 2008-2012 Colin MacDonald
- // No rights reserved: this software is in the public domain.
- #include "testUtils.h"
- using namespace irr;
- using namespace core;
- //! This was an older Irrlicht implementation, tested against for reference.
- static inline u32 old_strtol10(const char* in, const char** out=0)
- {
- u32 value = 0;
- while ( ( *in >= '0') && ( *in <= '9' ))
- {
- value = ( value * 10 ) + ( *in - '0' );
- ++in;
- }
- if (out)
- *out = in;
- return value;
- }
- //! This was an older Irrlicht implementation, tested against for reference.
- static inline const char* old_fast_atof_move( const char* c, float& out)
- {
- bool inv = false;
- const char *t;
- float f;
- if (*c=='-')
- {
- ++c;
- inv = true;
- }
- //f = (float)strtol(c, &t, 10);
- f = (float) old_strtol10 ( c, &c );
- if (*c == '.')
- {
- ++c;
- //float pl = (float)strtol(c, &t, 10);
- float pl = (float) old_strtol10 ( c, &t );
- pl *= fast_atof_table[t-c];
- f += pl;
- c = t;
- if (*c == 'e')
- {
- ++c;
- //float exp = (float)strtol(c, &t, 10);
- bool einv = (*c=='-');
- if (einv)
- ++c;
- float exp = (float)old_strtol10(c, &c);
- if (einv)
- exp *= -1.0f;
- f *= (float)pow(10.0f, exp);
- }
- }
- if (inv)
- f *= -1.0f;
- out = f;
- return c;
- }
- //! This was an older Irrlicht implementation, tested against for reference.
- static inline float old_fast_atof(const char* c)
- {
- float ret;
- old_fast_atof_move(c, ret);
- return ret;
- }
- static bool testCalculation_atof(const char * valueString)
- {
- const f32 newFastValue = fast_atof(valueString);
- const f32 oldFastValue = old_fast_atof(valueString);
- const f32 atofValue = (f32)atof(valueString);
- logTestString("\n String '%s'\n New fast %.40f\n Old fast %.40f\n atof %.40f\n",
- valueString, newFastValue, oldFastValue, atofValue);
- const f32 diffNew = fabs(newFastValue - atofValue) ;
- const f32 diffOld = fabs(oldFastValue - atofValue) ;
- bool accurate = diffNew <= diffOld || equalsByUlp(diffNew, diffOld, 1);
- if(!accurate)
- logTestString("*** ERROR - less accurate than old method ***\n\n");
- return accurate;
- }
- static bool testCalculation_strtol(const char * valueString)
- {
- const s32 newFastValue = strtol10(valueString);
- const s32 oldFastValue = old_strtol10(valueString);
- const s32 strtolValue = (s32)clamp(strtol(valueString, 0, 10), (long int)INT_MIN, (long int)INT_MAX);
- logTestString("\n String '%s'\n New fast %d\n Old fast %d\n strtol %d\n",
- valueString, newFastValue, oldFastValue, strtolValue);
- bool accurate = (newFastValue == strtolValue) || (oldFastValue != strtolValue);
- if (!accurate)
- logTestString("*** ERROR - wrong calculation in new method ***\n\n");
- return accurate;
- }
- //! Test both the accuracy and speed of Irrlicht's fast_atof() implementation.
- bool test_fast_atof(void)
- {
- bool accurate = true;
- accurate &= testCalculation_atof("340282346638528859811704183484516925440.000000");
- accurate &= testCalculation_atof("3.402823466e+38F");
- accurate &= testCalculation_atof("3402823466e+29F");
- accurate &= testCalculation_atof("-340282346638528859811704183484516925440.000000");
- accurate &= testCalculation_atof("-3.402823466e+38F");
- accurate &= testCalculation_atof("-3402823466e+29F");
- accurate &= testCalculation_atof("34028234663852885981170418348451692544.000000");
- accurate &= testCalculation_atof("3.402823466e+37F");
- accurate &= testCalculation_atof("3402823466e+28F");
- accurate &= testCalculation_atof("-34028234663852885981170418348451692544.000000");
- accurate &= testCalculation_atof("-3.402823466e+37F");
- accurate &= testCalculation_atof("-3402823466e+28F");
- accurate &= testCalculation_atof(".00234567");
- accurate &= testCalculation_atof("-.00234567");
- accurate &= testCalculation_atof("0.00234567");
- accurate &= testCalculation_atof("-0.00234567");
- accurate &= testCalculation_atof("1.175494351e-38F");
- accurate &= testCalculation_atof("1175494351e-47F");
- accurate &= testCalculation_atof("1.175494351e-37F");
- accurate &= testCalculation_atof("1.175494351e-36F");
- accurate &= testCalculation_atof("-1.175494351e-36F");
- accurate &= testCalculation_atof("123456.789");
- accurate &= testCalculation_atof("-123456.789");
- accurate &= testCalculation_atof("0000123456.789");
- accurate &= testCalculation_atof("-0000123456.789");
- accurate &= testCalculation_atof("-0.0690462109446526");
- accurate &= testCalculation_atof("0.11999999731779099"); // more numbers past dot than in lookup table
- accurate &= testCalculation_atof("0.119999997317790999");
- if (!accurate)
- {
- logTestString("Calculation is not accurate, so the speed is irrelevant\n");
- return false;
- }
- #ifndef _DEBUG // it's only faster in release
- IrrlichtDevice* device = createDevice(video::EDT_NULL);
- if (!device)
- return false;
- ITimer* timer = device->getTimer();
- const int ITERATIONS = 100000;
- int i;
- f32 value;
- u32 then = timer->getRealTime();
- for(i = 0; i < ITERATIONS; ++i)
- value = (f32)atof("-340282346638528859811704183484516925440.000000");
- const u32 atofTime = timer->getRealTime() - then;
- then += atofTime;
- for(i = 0; i < ITERATIONS; ++i)
- value = fast_atof("-340282346638528859811704183484516925440.000000");
- const u32 fastAtofTime = timer->getRealTime() - then;
- then += fastAtofTime;
- for(i = 0; i < ITERATIONS; ++i)
- value = old_fast_atof("-340282346638528859811704183484516925440.000000");
- const u32 oldFastAtofTime = timer->getRealTime() - then;
- logTestString("Speed test\n atof time = %d\n fast_atof Time = %d\nold fast_atof time = %d\n",
- atofTime, fastAtofTime, oldFastAtofTime);
- device->closeDevice();
- device->run();
- device->drop();
- if(fastAtofTime > (1.2f*atofTime))
- {
- logTestString("The fast method is slower than atof()\n");
- return false;
- }
- #endif // #ifndef _DEBUG
- return true;
- }
- //! Test both the accuracy and speed of Irrlicht's strtol10() implementation.
- bool test_strtol(void)
- {
- bool accurate = true;
- accurate &= testCalculation_strtol("340282346638528859811704183484516925440");
- accurate &= testCalculation_strtol("3402823466");
- accurate &= testCalculation_strtol("3402823466e+29F");
- accurate &= testCalculation_strtol("-340282346638528859811704183484516925440");
- accurate &= testCalculation_strtol("-3402823466");
- accurate &= testCalculation_strtol("-3402823466e+29F");
- accurate &= testCalculation_strtol("402823466385288598117");
- accurate &= testCalculation_strtol("402823466");
- accurate &= testCalculation_strtol("402823466e+28F");
- accurate &= testCalculation_strtol("402823466385288598117");
- accurate &= testCalculation_strtol("-402823466");
- accurate &= testCalculation_strtol("-402823466e+28F");
- accurate &= testCalculation_strtol(".00234567");
- accurate &= testCalculation_strtol("-234567");
- accurate &= testCalculation_strtol("234567");
- accurate &= testCalculation_strtol("-234567");
- accurate &= testCalculation_strtol("1175494351");
- accurate &= testCalculation_strtol("11754943512");
- accurate &= testCalculation_strtol("11754943513");
- accurate &= testCalculation_strtol("11754943514");
- accurate &= testCalculation_strtol("-1175494351");
- accurate &= testCalculation_strtol("123456789");
- accurate &= testCalculation_strtol("-123456789");
- accurate &= testCalculation_strtol("123456.789");
- accurate &= testCalculation_strtol("-123456.789");
- accurate &= testCalculation_strtol("-109446526");
- if(!accurate)
- {
- logTestString("Calculation is not accurate, so the speed is irrelevant\n");
- return false;
- }
- #ifndef _DEBUG // it's only faster in release
- IrrlichtDevice* device = createDevice(video::EDT_NULL);
- if (!device)
- return false;
- ITimer* timer = device->getTimer();
- const int ITERATIONS = 1000000;
- int i;
- s32 value;
- u32 then = timer->getRealTime();
- for(i = 0; i < ITERATIONS; ++i)
- value = strtol("-3402823466", 0, 10);
- const u32 strtolTime = timer->getRealTime() - then;
- then += strtolTime;
- for(i = 0; i < ITERATIONS; ++i)
- value = strtol10("-3402823466");
- const u32 strtol10Time = timer->getRealTime() - then;
- then += strtol10Time;
- for(i = 0; i < ITERATIONS; ++i)
- value = old_strtol10("-3402823466");
- const u32 oldstrtol10Time = timer->getRealTime() - then;
- logTestString("Speed test\n strtol time = %d\n strtol10 time = %d\nold strtol10 time = %d\n",
- strtolTime, strtol10Time, oldstrtol10Time);
- device->closeDevice();
- device->run();
- device->drop();
- if (strtol10Time > (1.2f*strtolTime))
- {
- logTestString("The fast method is slower than strtol()\n");
- return false;
- }
- #endif // #ifndef _DEBUG
- return true;
- }
- bool fast_atof(void)
- {
- bool ok = true;
- ok &= test_fast_atof() ;
- ok &= test_strtol();
- return ok;
- }
|