diff options
author | 2015-03-19 15:10:36 +0100 | |
---|---|---|
committer | 2015-03-19 15:10:36 +0100 | |
commit | f329d0908af35fd17bdc4dfeb87046dcaa6e6937 (patch) | |
tree | 7544488c7ffe9e2ea4ee8be1f45847bd41fc67f4 /Eigen/src | |
parent | cc0f89eb3b07c65efb2b73890e4e7ac83525700a (diff) |
Improve random number generation for integer and add unit test
Diffstat (limited to 'Eigen/src')
-rw-r--r-- | Eigen/src/Core/MathFunctions.h | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 0fde5c71e..e1b233d82 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -522,28 +522,24 @@ struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus> template<typename Scalar> struct random_default_impl<Scalar, false, true> { - typedef typename NumTraits<Scalar>::NonInteger NonInteger; - static inline Scalar run(const Scalar& x, const Scalar& y) { using std::max; - Scalar range = (max)(Scalar(0),Scalar(y-x)); - Scalar offset = 0; - if(range<=RAND_MAX) - { - // rejection sampling - int divisor = RAND_MAX/(range+1); - - do { - offset = Scalar(std::rand() / divisor); - } while (offset > range); - } - else - { - offset = std::rand() * range; - } - - return x + offset; + using std::min; + typedef typename conditional<NumTraits<Scalar>::IsSigned,std::ptrdiff_t,std::size_t>::type ScalarX; + if(y<x) + return x; + std::size_t range = ScalarX(y)-ScalarX(x); + std::size_t offset = 0; + // rejection sampling + std::size_t divisor = (range+RAND_MAX-1)/(range+1); + std::size_t multiplier = (range+RAND_MAX-1)/std::size_t(RAND_MAX); + + do { + offset = ( (std::size_t(std::rand()) * multiplier) / divisor ); + } while (offset > range); + + return Scalar(ScalarX(x) + offset); } static inline Scalar run() |