Fix cvtFast and tests
We might still want to change the actual behaviour though, see the FIXME comments.
This commit is contained in:
@@ -38,8 +38,15 @@ int cvtFloatToString(float flt_value, char *pdest,
|
||||
char *startAddr;
|
||||
|
||||
/* can this routine handle this conversion */
|
||||
if (isnan(flt_value) || precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) {
|
||||
sprintf(pdest,"%12.5e",(double)flt_value);
|
||||
if (isnan(flt_value) || precision > 8 ||
|
||||
flt_value > 10000000.0 || flt_value < -10000000.0) {
|
||||
if (precision > 8 || flt_value >= 1e8 || flt_value <= -1e8) {
|
||||
if (precision > 12) precision = 12; /* FIXME */
|
||||
sprintf(pdest, "%*.*e", precision+6, precision, (double) flt_value);
|
||||
} else {
|
||||
if (precision > 3) precision = 3; /* FIXME */
|
||||
sprintf(pdest, "%.*f", precision, (double) flt_value);
|
||||
}
|
||||
return((int)strlen(pdest));
|
||||
}
|
||||
startAddr = pdest;
|
||||
|
||||
@@ -22,30 +22,44 @@ public:
|
||||
void execute ();
|
||||
protected:
|
||||
char _pDst[128];
|
||||
double _srcVal;
|
||||
double _srcDbl;
|
||||
float _srcFlt;
|
||||
unsigned short _prec;
|
||||
static unsigned const _nUnrolled = 10;
|
||||
static const unsigned _uSecPerSec = 1000000;
|
||||
static unsigned const _nIterations = 10000;
|
||||
virtual const char *_name(void) = 0;
|
||||
virtual int _maxPrecision(void) = 0;
|
||||
virtual void _target () = 0;
|
||||
void _measure ();
|
||||
Test ( const Test & );
|
||||
Test & operator = ( Test & );
|
||||
};
|
||||
|
||||
class TestCvtFastDouble : public Test {
|
||||
class TestCvtFastFloat : public Test {
|
||||
protected:
|
||||
void _target ();
|
||||
const char *_name (void) { return "cvtFloatToString"; }
|
||||
int _maxPrecision(void) { return 12; }
|
||||
};
|
||||
|
||||
class TestCvtFastDouble : public Test {
|
||||
protected:
|
||||
void _target (void);
|
||||
const char *_name (void) { return "cvtDoubleToString"; }
|
||||
int _maxPrecision(void) { return 17; }
|
||||
};
|
||||
|
||||
class TestSNPrintf : public Test {
|
||||
protected:
|
||||
void _target ();
|
||||
const char *_name (void) { return "epicsSnprintf"; }
|
||||
int _maxPrecision(void) { return 17; }
|
||||
};
|
||||
|
||||
Test ::
|
||||
Test () :
|
||||
_srcVal ( 0.0 ), _prec ( 0 )
|
||||
_srcDbl ( 0.0 ), _prec ( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -55,28 +69,31 @@ Test :: ~Test ()
|
||||
|
||||
void Test :: execute ()
|
||||
{
|
||||
static const unsigned lowPrecision = 2;
|
||||
static const unsigned highPrecision = DBL_MANT_DIG;
|
||||
|
||||
for ( unsigned i = 0; i < 3; i++ ) {
|
||||
double mVal = rand ();
|
||||
mVal /= (RAND_MAX + 1.0);
|
||||
double fEVal = rand ();
|
||||
fEVal /= (RAND_MAX + 1.0);
|
||||
fEVal *= DBL_MAX_EXP - DBL_MIN_EXP;
|
||||
fEVal += DBL_MIN_EXP;
|
||||
int eVal = static_cast < int > ( fEVal + 0.5 );
|
||||
_srcVal = ldexp ( mVal, eVal );
|
||||
for ( _prec = lowPrecision;
|
||||
_prec <= highPrecision; _prec += 4u ) {
|
||||
double eVal = rand ();
|
||||
eVal /= (RAND_MAX + 1.0);
|
||||
double dVal = eVal;
|
||||
dVal *= DBL_MAX_EXP - DBL_MIN_EXP;
|
||||
dVal += DBL_MIN_EXP;
|
||||
int dEVal = static_cast < int > ( dVal + 0.5 );
|
||||
float fVal = eVal;
|
||||
fVal *= FLT_MAX_EXP - FLT_MIN_EXP;
|
||||
fVal += FLT_MIN_EXP;
|
||||
int fEVal = static_cast < int > ( fVal + 0.5 );
|
||||
_srcDbl = ldexp ( mVal, dEVal );
|
||||
_srcFlt = ldexpf ( mVal, fEVal );
|
||||
for ( _prec = 0; _prec <= _maxPrecision(); _prec++ ) {
|
||||
_measure ();
|
||||
}
|
||||
_srcVal = rand ();
|
||||
_srcVal /= (RAND_MAX + 1.0);
|
||||
_srcVal *= 10.0;
|
||||
_srcVal -= 5.0;
|
||||
for ( _prec = lowPrecision;
|
||||
_prec <= highPrecision; _prec += 4u ) {
|
||||
_srcDbl = rand ();
|
||||
_srcDbl /= (RAND_MAX + 1.0);
|
||||
_srcDbl *= 10.0;
|
||||
_srcDbl -= 5.0;
|
||||
_srcFlt = (float) _srcDbl;
|
||||
for ( _prec = 0; _prec <= _maxPrecision(); _prec++ ) {
|
||||
_measure ();
|
||||
}
|
||||
}
|
||||
@@ -91,56 +108,72 @@ void Test :: _measure ()
|
||||
epicsTime end = epicsTime :: getCurrent ();
|
||||
double elapsed = end - beg;
|
||||
elapsed /= _nIterations * _nUnrolled;
|
||||
elapsed *= _uSecPerSec;
|
||||
printf ( " %4.4f usec, prec=%i, val=%4.4g, for %s\n",
|
||||
elapsed, _prec, _srcVal, typeid ( *this ).name () );
|
||||
printf ( "%17s: %12.9f sec, prec=%2i, out=%s\n",
|
||||
this->_name (), elapsed, _prec, _pDst );
|
||||
}
|
||||
|
||||
void TestCvtFastFloat :: _target ()
|
||||
{
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
cvtFloatToString ( _srcFlt, _pDst, _prec );
|
||||
}
|
||||
|
||||
void TestCvtFastDouble :: _target ()
|
||||
{
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcVal, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
cvtDoubleToString ( _srcDbl, _pDst, _prec );
|
||||
}
|
||||
|
||||
void TestSNPrintf :: _target ()
|
||||
{
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
|
||||
static_cast < int > ( _prec ), _srcVal );
|
||||
static_cast < int > ( _prec ), _srcDbl );
|
||||
}
|
||||
|
||||
MAIN(cvtFastPerform)
|
||||
{
|
||||
TestCvtFastFloat testCvtFastFloat;
|
||||
TestCvtFastDouble testCvtFastDouble;
|
||||
TestSNPrintf testSNPrintf;
|
||||
|
||||
testCvtFastFloat.execute ();
|
||||
testCvtFastDouble.execute ();
|
||||
testSNPrintf.execute ();
|
||||
|
||||
|
||||
@@ -326,12 +326,12 @@ MAIN(cvtFastTest)
|
||||
testDiag("------------------------------------------------------");
|
||||
testDiag("** Positive Float scientific **");
|
||||
tryFString(Float, 1e+08, 0, 6);
|
||||
tryFString(Float, 1e+08, 1, 8);
|
||||
tryFString(Float, 1e+08, 2, 9);
|
||||
tryFString(Float, 1e+08, 3, 10);
|
||||
tryFString(Float, 1e+08, 4, 11);
|
||||
tryFString(Float, 1e+08, 5, 12);
|
||||
tryFString(Float, 1e+08, 6, 13);
|
||||
tryFString(Float, 1e+08, 1, 7);
|
||||
tryFString(Float, 1e+08, 2, 8);
|
||||
tryFString(Float, 1e+08, 3, 9);
|
||||
tryFString(Float, 1e+08, 4, 10);
|
||||
tryFString(Float, 1e+08, 5, 11);
|
||||
tryFString(Float, 1e+08, 6, 12);
|
||||
|
||||
testDiag("------------------------------------------------------");
|
||||
testDiag("** Positive Double fixed-point **");
|
||||
|
||||
Reference in New Issue
Block a user