Sometimes random<short>(0, n) returns n + 1. This could be responsible for some out of bounds errors in the tests (I've tracked a failure in sparse_basic_1 to this). The problem is in this formula (Eigen/src/Core/MathFunctions.h): static inline Scalar run(const Scalar& x, const Scalar& y) { return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1))); } When Scalar is a 16-bit int, NonInteger is a 32-bit float with 24 bits for the mantissa. However, std::rand() is wider than Scalar since it produces 31 meaningful bits. So when std::rand() returns a value that is very close to RAND_MAX, 24-bit mantissa cannot distinguish them. Here's a plain C snippet that shows this formula in action: #include <stdio.h> int main() { float f = (float) (18 + 1) * 2147483640 / (2147483647 + (float) 1); printf("%f %d\n", f, (int) f); return 0; } which prints "19.000000 19". The most obvious solution is to replace NonInteger with double for this case. But there's probably some similar effect for 64-bit integers and doubles. So perhaps you might want to treat 64-bit Scalar as a special case and replace NonInteger with uint64_t.
I copied the improved rand_impl from the devel branch (as well as the corresponding unit test): https://bitbucket.org/eigen/eigen/commits/d60e23b8af1
That was quick, thanks! Please note that 64 bit size of size_t is not guaranteed though.
Indeed, another approach would be to recursively call rand() when range>RAND_MAX: int n = 1; int rand_max = RAND_MAX; while(rand_max<range) { n++; rand_max = rand_max*(RAND_MAX+1)+RAND_MAX; } divisor = ((rand_max+1)/range); do { x = xrand(n); } while(x>=range * divisor); return x / divisor; with: int xrand(n) { if(n==1) return std::rand(); else return xrand(n-1) * (RAND_MAX+1) + std::rand(); }
Regarding rand, I fixed some overflow issues: https://bitbucket.org/eigen/eigen/commits/00d109dc8349/ https://bitbucket.org/eigen/eigen/commits/8eb116bb13f9/ (3.2)
-- GitLab Migration Automatic Message -- This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/1275.