177 lines
4.7 KiB
C++
177 lines
4.7 KiB
C++
// Copyright (C) 2008-2009 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(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);
|
|
|
|
bool accurate = fabs(newFastValue - atofValue) <= fabs(oldFastValue - atofValue);
|
|
|
|
if(!accurate)
|
|
logTestString("*** ERROR - less accurate than old method ***\n\n");
|
|
|
|
return accurate;
|
|
}
|
|
|
|
//! Test both the accuracy and speed of Irrlicht's fast_atof() implementation.
|
|
bool fast_atof(void)
|
|
{
|
|
bool accurate = true;
|
|
|
|
accurate &= testCalculation("340282346638528859811704183484516925440.000000");
|
|
accurate &= testCalculation("3.402823466e+38F");
|
|
accurate &= testCalculation("3402823466e+29F");
|
|
accurate &= testCalculation("-340282346638528859811704183484516925440.000000");
|
|
accurate &= testCalculation("-3.402823466e+38F");
|
|
accurate &= testCalculation("-3402823466e+29F");
|
|
accurate &= testCalculation("34028234663852885981170418348451692544.000000");
|
|
accurate &= testCalculation("3.402823466e+37F");
|
|
accurate &= testCalculation("3402823466e+28F");
|
|
accurate &= testCalculation("-34028234663852885981170418348451692544.000000");
|
|
accurate &= testCalculation("-3.402823466e+37F");
|
|
accurate &= testCalculation("-3402823466e+28F");
|
|
accurate &= testCalculation(".00234567");
|
|
accurate &= testCalculation("-.00234567");
|
|
accurate &= testCalculation("0.00234567");
|
|
accurate &= testCalculation("-0.00234567");
|
|
accurate &= testCalculation("1.175494351e-38F");
|
|
accurate &= testCalculation("1175494351e-47F");
|
|
accurate &= testCalculation("1.175494351e-37F");
|
|
accurate &= testCalculation("1.175494351e-36F");
|
|
accurate &= testCalculation("-1.175494351e-36F");
|
|
accurate &= testCalculation("123456.789");
|
|
accurate &= testCalculation("-123456.789");
|
|
accurate &= testCalculation("0000123456.789");
|
|
accurate &= testCalculation("-0000123456.789");
|
|
accurate &= testCalculation("-0.0690462109446526");
|
|
|
|
if(!accurate)
|
|
{
|
|
logTestString("Calculation is not accurate, so the speed is irrelevant\n");
|
|
return false;
|
|
}
|
|
|
|
IrrlichtDevice* device = createDevice(video::EDT_NULL);
|
|
if (!device)
|
|
return false;
|
|
ITimer* timer = device->getTimer();
|
|
|
|
enum { 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(" atof time = %d\n fast_atof Time = %d\nold fast_atof time = %d\n",
|
|
atofTime, fastAtofTime, oldFastAtofTime);
|
|
|
|
device->drop();
|
|
|
|
if(fastAtofTime > (1.2f*atofTime))
|
|
{
|
|
logTestString("The fast method is slower than atof()\n");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|