diff --git a/svm.cpp b/svm.cpp index 338c50e4..5e31599d 100644 --- a/svm.cpp +++ b/svm.cpp @@ -7,6 +7,9 @@ #include #include #include +#ifdef _WIN32 +#include +#endif #include "svm.h" int libsvm_version = LIBSVM_VERSION; typedef float Qfloat; @@ -38,6 +41,33 @@ static inline double powi(double base, int times) #define TAU 1e-12 #define Malloc(type,n) (type *)malloc((n)*sizeof(type)) +// New function to ensure the same behaviour for random number generation on windows and linux +inline int myrand() { +// In MS Visual Studio (2012) RAND_MAX = 0x7FFF (15bit) = 32767 +// In Linux GCC (4.6) 32bits RAND_MAX = 0x7FFFFFFF (31bit) = 2147483647 +// In Linux GCC (4.6) 64bits RAND_MAX = 0x7FFFFFFFFFFFFFFF (63 bits) = 9223372036854775807 +// so in MS Visual Studio we need to call rand() several times to always ensure the same random number range than in Linux GCC +#if RAND_MAX != INT_MAX + #if INT_MAX == 0x7FFFFFFF + // make a 31bit random number by using several 15bit rand() + // info("Fixing random number generator for 32 bits ints. RAND_MAX=%d INT_MAX=%d\n", RAND_MAX, INT_MAX); + return ( (__int32)rand() << 16) + ( (__int32)rand() << 1) + ( (__int32)rand() >> 14); + #elif INT_MAX == 0x7FFFFFFFFFFFFFFF + // make a 63bit random number by using several 15bit rand() + // info("Fixing random number generator for 64 bits ints. RAND_MAX=%d INT_MAX=%d\n", RAND_MAX, INT_MAX); + return ( ( (__int64)rand() << 48) + ( (__int64)rand() << 33) + ( (__int64)rand() << 18) + ( (__int64)rand() << 3) + ( (__int64)rand() >> 12) ); + #else + //fallback - should never happen on 32 or 64 bits windows systems + info("Random number generator is not fixed for this system. Please report issue. RAND_MAX=%d INT_MAX=%d\n", RAND_MAX, INT_MAX); + exit(1); + #endif +#else + // In Linux GCC (4.6) 32bits RAND_MAX = 0x7FFFFFFF (31bit) or 64bits RAND_MAX = 0x7FFFFFFFFFFFFFFF (63 bits) + // nothing special to do + return rand(); +#endif +} + static void print_string_stdout(const char *s) { fputs(s,stdout); @@ -1903,7 +1933,7 @@ static void svm_binary_svc_probability( for(i=0;il;i++) perm[i]=i; for(i=0;il;i++) { - int j = i+rand()%(prob->l-i); + int j = i+myrand()%(prob->l-i); swap(perm[i],perm[j]); } for(i=0;i