Add rand and randf functions for generating random numbers

This commit is contained in:
nyalldawson 2013-05-11 19:12:49 +10:00
parent a14adc407c
commit 167cc95e35
5 changed files with 93 additions and 1 deletions

View File

@ -0,0 +1,16 @@
<h3>rand() function</h3>
Returns a random integer within the range specified by the minimum and
maximum argument (inclusive).
<br>
This function takes two arguments.
<h4>Syntax</h4>
<code>rand(min, max)</code><br>
<h4>Arguments</h4>
<code>min</code> - an integer representing the smallest possible random number desired.<br>
<code>max</code> - an integer representing the largest possible random number desired.
<br>
<h4>Example</h4>
<!-- Show example of function.-->
<code>rand(1, 10) &rarr; 8</code><br>

View File

@ -0,0 +1,16 @@
<h3>rand() function</h3>
Returns a random float within the range specified by the minimum and
maximum argument (inclusive).
<br>
This function takes two arguments.
<h4>Syntax</h4>
<code>randf(min, max)</code><br>
<h4>Arguments</h4>
<code>min</code> - a float representing the smallest possible random number desired.<br>
<code>max</code> - a float representing the largest possible random number desired.
<br>
<h4>Example</h4>
<!-- Show example of function.-->
<code>randf(1, 10) &rarr; 4.59258286403147</code><br>

View File

@ -294,6 +294,9 @@ int main( int argc, char *argv[] )
SetUnhandledExceptionFilter( qgisCrashDump );
#endif
// initialize random number seed
srand( time( NULL ) );
/////////////////////////////////////////////////////////////////
// Command line options 'behaviour' flag setup
////////////////////////////////////////////////////////////////

View File

@ -410,6 +410,27 @@ static QVariant fcnLog( const QVariantList& values, QgsFeature* , QgsExpression*
return QVariant();
return QVariant( log( x ) / log( b ) );
}
static QVariant fcnRndF( const QVariantList& values, QgsFeature* , QgsExpression* parent )
{
double min = getDoubleValue( values.at( 0 ), parent );
double max = getDoubleValue( values.at( 1 ), parent );
if ( max < min )
return QVariant();
// Return a random double in the range [min, max] (inclusive)
double f = ( double )rand() / RAND_MAX;
return QVariant( min + f * ( max - min ) ) ;
}
static QVariant fcnRnd( const QVariantList& values, QgsFeature* , QgsExpression* parent )
{
int min = getIntValue( values.at( 0 ), parent );
int max = getIntValue( values.at( 1 ), parent );
if ( max < min )
return QVariant();
// Return a random integer in the range [min, max] (inclusive)
return QVariant( min + ( rand() % ( int )( max - min + 1 ) ) );
}
static QVariant fcnToInt( const QVariantList& values, QgsFeature* , QgsExpression* parent )
{
return QVariant( getIntValue( values.at( 0 ), parent ) );
@ -1207,7 +1228,7 @@ const QStringList &QgsExpression::BuiltinFunctions()
<< "sqrt" << "cos" << "sin" << "tan"
<< "asin" << "acos" << "atan" << "atan2"
<< "exp" << "ln" << "log10" << "log"
<< "round" << "toint" << "toreal" << "tostring"
<< "round" << "rand" << "randf" << "toint" << "toreal" << "tostring"
<< "todatetime" << "todate" << "totime" << "tointerval"
<< "coalesce" << "regexp_match" << "$now" << "age" << "year"
<< "month" << "week" << "day" << "hour"
@ -1246,6 +1267,8 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "log10", 1, fcnLog10, QObject::tr( "Math" ) )
<< new StaticFunction( "log", 2, fcnLog, QObject::tr( "Math" ) )
<< new StaticFunction( "round", -1, fcnRound, QObject::tr( "Math" ) )
<< new StaticFunction( "rand", 2, fcnRnd, QObject::tr( "Math" ) )
<< new StaticFunction( "randf", 2, fcnRndF, QObject::tr( "Math" ) )
<< new StaticFunction( "$pi", 0, fcnPi, QObject::tr( "Math" ) )
<< new StaticFunction( "toint", 1, fcnToInt, QObject::tr( "Conversions" ) )
<< new StaticFunction( "toreal", 1, fcnToReal, QObject::tr( "Conversions" ) )

View File

@ -454,6 +454,40 @@ class TestQgsExpression: public QObject
QCOMPARE( v.toInt(), 200 );
}
void eval_rand()
{
QgsExpression exp1( "rand(1,10)" );
QVariant v1 = exp1.evaluate();
QCOMPARE( v1.toInt() <= 10, true );
QCOMPARE( v1.toInt() >= 1, true );
QgsExpression exp2( "rand(-5,-5)" );
QVariant v2 = exp2.evaluate();
QCOMPARE( v2.toInt(), -5 );
// Invalid expression since max<min
QgsExpression exp3( "rand(10,1)" );
QVariant v3 = exp3.evaluate();
QCOMPARE( v3.type(), QVariant::Invalid );
}
void eval_randf()
{
QgsExpression exp1( "randf(1.5,9.5)" );
QVariant v1 = exp1.evaluate();
QCOMPARE( v1.toDouble() <= 9.5, true );
QCOMPARE( v1.toDouble() >= 1.5, true );
QgsExpression exp2( "randf(-0.0005,-0.0005)" );
QVariant v2 = exp2.evaluate();
QCOMPARE( v2.toDouble(), -0.0005 );
// Invalid expression since max<min
QgsExpression exp3( "randf(9.3333,1.784)" );
QVariant v3 = exp3.evaluate();
QCOMPARE( v3.type(), QVariant::Invalid );
}
void referenced_columns()
{
QSet<QString> expectedCols;