diff --git a/common/rng_sfmt.cpp b/common/rng_sfmt.cpp index e2c38526..2e93e44b 100644 --- a/common/rng_sfmt.cpp +++ b/common/rng_sfmt.cpp @@ -1,6 +1,7 @@ #include "rng_sfmt.h" #include #include +#include // This is from gcc sources, namely from fixincludes/inclhack.def // On C++11 systems, could be included instead. @@ -57,12 +58,17 @@ RNG_SFMT::RNG_SFMT(QObject *parent) */ unsigned int RNG_SFMT::getNumber(unsigned int min, unsigned int max) { - // This all makes no sense if min > max. - // So in debug mode Q_ASSERT will print a warning... - Q_ASSERT(min <= max); - // ... and at runtime min and max will be swapped; this should never happen. - if(min > max) - std::swap(min, max); + // This all makes no sense if min > max, which should never happen. + if(min > max) { + throw std::invalid_argument( + QString("Invalid bounds for RNG: min > max! Values were: min = " + + QString::number(min) + ", max = " + + QString::number(max) + + ". This is either a bug or something even more serious happened." + ).toStdString()); + // at this point, the method exits. No return value is needed, because + // basically the exception itself is returned. + } // First compute the diameter (aka size, length) of the [min, max] interval const unsigned int diameter = max - min + 1; diff --git a/common/rng_sfmt.h b/common/rng_sfmt.h index 80ff9f2f..3134e91d 100644 --- a/common/rng_sfmt.h +++ b/common/rng_sfmt.h @@ -7,7 +7,14 @@ /** * This class represents the random number generator. - * It uses the SIMD-oriented Fast Mersenne Twister code v1.4.1 from + * Usage instructions: + * Create an instance of RNG_SFMT, then call getNumber(min, max). + * You should never call this function with min > max, this throws a + * std::invalid_argument exception. It is best practice to use getNumber() in a try block + * and catch the exception if min, max are entered by the user or computed somehow. + * + * Technical details: + * The RNG uses the SIMD-oriented Fast Mersenne Twister code v1.4.1 from * http://www.math.sci.hiroshima-u.ac.jp/~%20m-mat/MT/SFMT/index.html * To use this RNG, the class needs a sfmt_t structure for the RNG's internal state. * It has to be initialized by sfmt_init_gen_rand() which is done in the constructor.