/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Contributor(s): * Copyright (C) 2012 Tino Kluge <tino.kluge@hrz.tu-chemnitz.de>
*/
// this is nothing but a simple wrapper around // the std::random generators
namespace comphelper::rng
{ // underlying random number generator // std::mt19937 implements the Mersenne twister algorithm which // is fast and has good statistical properties, it produces integers // in the range of [0, 2^32-1] internally // memory requirement: 625*sizeof(uint32_t) // http://en.wikipedia.org/wiki/Mersenne_twister #define STD_RNG_ALGO std::mt19937
void reseed()
{ // make RR easier to use, breaks easily without the RNG being repeatable bool bRepeatable = (getenv("SAL_RAND_REPEATABLE") != nullptr) || (getenv("RR") != nullptr); // valgrind on some platforms (e.g.Ubuntu16.04) does not support the new Intel RDRAND instructions, // which leads to "Illegal Opcode" errors, so just turn off randomness. #ifdefined HAVE_VALGRIND_HEADERS if (RUNNING_ON_VALGRIND)
bRepeatable = true; #endif if (bRepeatable)
{
global_rng.seed(42); return;
}
// initialises the state of the global random number generator // should only be called once. // (note, a few std::variate_generator<> (like normal) have their // own state which would need a reset as well to guarantee identical // sequence of numbers, e.g. via myrand.distribution().reset())
global_rng.seed(seed ^ time(nullptr));
}
};
// uniform ints [a,b] distribution int uniform_int_distribution(int a, int b)
{
std::uniform_int_distribution<int> dist(a, b); auto& gen = GetTheRandomNumberGenerator();
std::scoped_lock<std::mutex> g(gen.mutex); return dist(gen.global_rng);
}
// uniform ints [a,b] distribution unsignedint uniform_uint_distribution(unsignedint a, unsignedint b)
{
std::uniform_int_distribution<unsignedint> dist(a, b); auto& gen = GetTheRandomNumberGenerator();
std::scoped_lock<std::mutex> g(gen.mutex); return dist(gen.global_rng);
}
// uniform size_t [a,b] distribution
size_t uniform_size_distribution(size_t a, size_t b)
{
std::uniform_int_distribution<size_t> dist(a, b); auto& gen = GetTheRandomNumberGenerator();
std::scoped_lock<std::mutex> g(gen.mutex); return dist(gen.global_rng);
}
// uniform size_t [a,b) distribution double uniform_real_distribution(double a, double b)
{
assert(a < b);
std::uniform_real_distribution<double> dist(a, b); auto& gen = GetTheRandomNumberGenerator();
std::scoped_lock<std::mutex> g(gen.mutex); return dist(gen.global_rng);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.