Skip to content

Commit 167cc95

Browse files
committed
Add rand and randf functions for generating random numbers
1 parent a14adc4 commit 167cc95

File tree

5 files changed

+93
-1
lines changed

5 files changed

+93
-1
lines changed

resources/function_help/rand-en_US

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h3>rand() function</h3>
2+
Returns a random integer within the range specified by the minimum and
3+
maximum argument (inclusive).
4+
<br>
5+
This function takes two arguments.
6+
<h4>Syntax</h4>
7+
<code>rand(min, max)</code><br>
8+
9+
<h4>Arguments</h4>
10+
<code>min</code> - an integer representing the smallest possible random number desired.<br>
11+
<code>max</code> - an integer representing the largest possible random number desired.
12+
<br>
13+
14+
<h4>Example</h4>
15+
<!-- Show example of function.-->
16+
<code>rand(1, 10) &rarr; 8</code><br>

resources/function_help/randf-en_US

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h3>rand() function</h3>
2+
Returns a random float within the range specified by the minimum and
3+
maximum argument (inclusive).
4+
<br>
5+
This function takes two arguments.
6+
<h4>Syntax</h4>
7+
<code>randf(min, max)</code><br>
8+
9+
<h4>Arguments</h4>
10+
<code>min</code> - a float representing the smallest possible random number desired.<br>
11+
<code>max</code> - a float representing the largest possible random number desired.
12+
<br>
13+
14+
<h4>Example</h4>
15+
<!-- Show example of function.-->
16+
<code>randf(1, 10) &rarr; 4.59258286403147</code><br>

src/app/main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@ int main( int argc, char *argv[] )
294294
SetUnhandledExceptionFilter( qgisCrashDump );
295295
#endif
296296

297+
// initialize random number seed
298+
srand( time( NULL ) );
299+
297300
/////////////////////////////////////////////////////////////////
298301
// Command line options 'behaviour' flag setup
299302
////////////////////////////////////////////////////////////////

src/core/qgsexpression.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,27 @@ static QVariant fcnLog( const QVariantList& values, QgsFeature* , QgsExpression*
410410
return QVariant();
411411
return QVariant( log( x ) / log( b ) );
412412
}
413+
static QVariant fcnRndF( const QVariantList& values, QgsFeature* , QgsExpression* parent )
414+
{
415+
double min = getDoubleValue( values.at( 0 ), parent );
416+
double max = getDoubleValue( values.at( 1 ), parent );
417+
if ( max < min )
418+
return QVariant();
419+
420+
// Return a random double in the range [min, max] (inclusive)
421+
double f = ( double )rand() / RAND_MAX;
422+
return QVariant( min + f * ( max - min ) ) ;
423+
}
424+
static QVariant fcnRnd( const QVariantList& values, QgsFeature* , QgsExpression* parent )
425+
{
426+
int min = getIntValue( values.at( 0 ), parent );
427+
int max = getIntValue( values.at( 1 ), parent );
428+
if ( max < min )
429+
return QVariant();
430+
431+
// Return a random integer in the range [min, max] (inclusive)
432+
return QVariant( min + ( rand() % ( int )( max - min + 1 ) ) );
433+
}
413434
static QVariant fcnToInt( const QVariantList& values, QgsFeature* , QgsExpression* parent )
414435
{
415436
return QVariant( getIntValue( values.at( 0 ), parent ) );
@@ -1207,7 +1228,7 @@ const QStringList &QgsExpression::BuiltinFunctions()
12071228
<< "sqrt" << "cos" << "sin" << "tan"
12081229
<< "asin" << "acos" << "atan" << "atan2"
12091230
<< "exp" << "ln" << "log10" << "log"
1210-
<< "round" << "toint" << "toreal" << "tostring"
1231+
<< "round" << "rand" << "randf" << "toint" << "toreal" << "tostring"
12111232
<< "todatetime" << "todate" << "totime" << "tointerval"
12121233
<< "coalesce" << "regexp_match" << "$now" << "age" << "year"
12131234
<< "month" << "week" << "day" << "hour"
@@ -1246,6 +1267,8 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
12461267
<< new StaticFunction( "log10", 1, fcnLog10, QObject::tr( "Math" ) )
12471268
<< new StaticFunction( "log", 2, fcnLog, QObject::tr( "Math" ) )
12481269
<< new StaticFunction( "round", -1, fcnRound, QObject::tr( "Math" ) )
1270+
<< new StaticFunction( "rand", 2, fcnRnd, QObject::tr( "Math" ) )
1271+
<< new StaticFunction( "randf", 2, fcnRndF, QObject::tr( "Math" ) )
12491272
<< new StaticFunction( "$pi", 0, fcnPi, QObject::tr( "Math" ) )
12501273
<< new StaticFunction( "toint", 1, fcnToInt, QObject::tr( "Conversions" ) )
12511274
<< new StaticFunction( "toreal", 1, fcnToReal, QObject::tr( "Conversions" ) )

tests/src/core/testqgsexpression.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,40 @@ class TestQgsExpression: public QObject
454454
QCOMPARE( v.toInt(), 200 );
455455
}
456456

457+
void eval_rand()
458+
{
459+
QgsExpression exp1( "rand(1,10)" );
460+
QVariant v1 = exp1.evaluate();
461+
QCOMPARE( v1.toInt() <= 10, true );
462+
QCOMPARE( v1.toInt() >= 1, true );
463+
464+
QgsExpression exp2( "rand(-5,-5)" );
465+
QVariant v2 = exp2.evaluate();
466+
QCOMPARE( v2.toInt(), -5 );
467+
468+
// Invalid expression since max<min
469+
QgsExpression exp3( "rand(10,1)" );
470+
QVariant v3 = exp3.evaluate();
471+
QCOMPARE( v3.type(), QVariant::Invalid );
472+
}
473+
474+
void eval_randf()
475+
{
476+
QgsExpression exp1( "randf(1.5,9.5)" );
477+
QVariant v1 = exp1.evaluate();
478+
QCOMPARE( v1.toDouble() <= 9.5, true );
479+
QCOMPARE( v1.toDouble() >= 1.5, true );
480+
481+
QgsExpression exp2( "randf(-0.0005,-0.0005)" );
482+
QVariant v2 = exp2.evaluate();
483+
QCOMPARE( v2.toDouble(), -0.0005 );
484+
485+
// Invalid expression since max<min
486+
QgsExpression exp3( "randf(9.3333,1.784)" );
487+
QVariant v3 = exp3.evaluate();
488+
QCOMPARE( v3.type(), QVariant::Invalid );
489+
}
490+
457491
void referenced_columns()
458492
{
459493
QSet<QString> expectedCols;

0 commit comments

Comments
 (0)