diff --git a/include/MUtils/Global.h b/include/MUtils/Global.h index 937a319..956ca94 100644 --- a/include/MUtils/Global.h +++ b/include/MUtils/Global.h @@ -85,6 +85,15 @@ class QProcess; */ namespace MUtils { + /** + * \brief This struct containes the parts of a floating-point number + */ + typedef struct + { + double intpart, fractpart; + } + fp_parts_t; + /** * \brief Rerieves the full path of the application's *Temp* folder. * @@ -329,6 +338,15 @@ namespace MUtils */ MUTILS_API QStringList available_codepages(const bool &noAliases = true); + /** + * \brief Break floating-point number into fractional and integral parts + * + * \param value The original floating-point value + * + * \return Returns a struct containing the fractional and integral parts + */ + MUTILS_API fp_parts_t break_fp(const double value); + //Internal namespace Internal { diff --git a/include/MUtils/Version.h b/include/MUtils/Version.h index 9c6d11d..da4f1a5 100644 --- a/include/MUtils/Version.h +++ b/include/MUtils/Version.h @@ -68,7 +68,7 @@ namespace MUtils #endif #elif defined(_MSC_VER) #if (_MSC_VER == 1913) - #if((_MSC_FULL_VER >= 191326128) && (_MSC_FULL_VER <= 191326128)) + #if((_MSC_FULL_VER >= 191326128) && (_MSC_FULL_VER <= 191326129)) "MSVC 2017.6"; #else #error Compiler version is not supported yet! diff --git a/src/Global.cpp b/src/Global.cpp index 026ddff..2028e69 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -63,13 +63,12 @@ //Per-thread init flag static QThreadStorage g_srand_flag; +//32-Bit wrapper for qrand() +#define QRAND() ((static_cast(qrand()) & 0xFFFF) | (static_cast(qrand()) << 16U)) + //Robert Jenkins' 96 bit Mix Function -static quint32 mix_function(const quint32 x, const quint32 y, const quint32 z) +static quint32 mix_function(quint32 a, quint32 b, quint32 c) { - quint32 a = x; - quint32 b = y; - quint32 c = z; - a=a-b; a=a-c; a=a^(c >> 13); b=b-c; b=b-a; b=b^(a << 8); c=c-a; c=c-b; c=c^(b >> 13); @@ -86,24 +85,30 @@ static quint32 mix_function(const quint32 x, const quint32 y, const quint32 z) static void seed_rand(void) { QDateTime build(MUtils::Version::lib_build_date(), MUtils::Version::lib_build_time()); - const quint32 seed = mix_function(MUtils::OS::process_id(), MUtils::OS::thread_id(), build.toMSecsSinceEpoch()); - qsrand(mix_function(clock(), time(NULL), seed)); + const quint32 seed_0 = mix_function(MUtils::OS::process_id(), MUtils::OS::thread_id(), build.toMSecsSinceEpoch()); + qsrand(mix_function(clock(), time(NULL), seed_0)); } static quint32 rand_fallback(void) { - Q_ASSERT(RAND_MAX >= 0xFFF); + Q_ASSERT(RAND_MAX >= 0x7FFF); + if (!(g_srand_flag.hasLocalData() && g_srand_flag.localData())) { seed_rand(); g_srand_flag.setLocalData(true); } - quint32 rnd = 0x32288EA3; - for (size_t i = 0; i < 3; i++) + + quint32 rnd_val = mix_function(0x32288EA3, clock(), time(NULL)); + + for (size_t i = 0; i < 42; i++) { - rnd = (rnd << 12) ^ qrand(); + rnd_val = mix_function(rnd_val, QRAND(), QRAND()); + rnd_val = mix_function(QRAND(), rnd_val, QRAND()); + rnd_val = mix_function(QRAND(), QRAND(), rnd_val); } - return rnd; + + return rnd_val; } quint32 MUtils::next_rand_u32(void) @@ -801,6 +806,17 @@ QStringList MUtils::available_codepages(const bool &noAliases) return codecList; } +/////////////////////////////////////////////////////////////////////////////// +// FP MATH SUPPORT +/////////////////////////////////////////////////////////////////////////////// + +MUtils::fp_parts_t MUtils::break_fp(const double value) +{ + fp_parts_t result; + result.fractpart = modf(value, &result.intpart); + return result; +} + /////////////////////////////////////////////////////////////////////////////// // SELF-TEST ///////////////////////////////////////////////////////////////////////////////