diff --git a/README.md b/README.md index 983df01..64c9df2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ BigInt

Arbitrary-sized integer class for C++

- --- [![Release version][release-shield]][release-link] @@ -200,14 +199,14 @@ * #### Random * #### `big_random` - Get a random `BigInt`, that either has a random number of digits (up to + Get a random positive `BigInt`, that either has a random number of digits (up to 1000), or a specific number of digits. ```c++ - // get a random BigInt that has a random number of digits (up to 1000): + // get a random postive BigInt that has a random number of digits (up to 1000): big1 = big_random(); - // get a random BigInt that has 12345 digits: + // get a random positive BigInt that has 12345 digits: big1 = big_random(12345); ``` diff --git a/include/functions/random.hpp b/include/functions/random.hpp index 10d08cc..cfda809 100644 --- a/include/functions/random.hpp +++ b/include/functions/random.hpp @@ -20,29 +20,42 @@ const size_t MAX_RANDOM_LENGTH = 1000; /* big_random (num_digits) ----------------------- - Returns a random BigInt with a specific number of digits. + Returns a random positive BigInt with a specific number of digits. */ BigInt big_random(size_t num_digits = 0) { - std::random_device rand_generator; // true random number generator - - if (num_digits == 0) // the number of digits were not specified + /** + * This generators needed to be created only once, + * because properly seeded std::mt19937 can generate + * 2^19937 - 1 potential states which is more than + * enough for most usecases + */ + + // seed sequence, seeded with true random generator + // used for better entropy + static std::seed_seq sseq{std::random_device{}()}; + // generator itself + static std::mt19937 gen{sseq}; + // different purpose distributions(cheap to create and use) + static std::uniform_int_distribution<> digit_distr(0, 9); + static std::uniform_int_distribution<> first_digit_distr(0, 9); + static std::uniform_int_distribution<> length_distribution(1, MAX_RANDOM_LENGTH); + // number to generate + static BigInt big_rand; + + // first digit + big_rand.value = std::to_string(first_digit_distr(gen)); + + if (num_digits == 0) + // the number of digits were not specified // use a random number for it: - num_digits = 1 + rand_generator() % MAX_RANDOM_LENGTH; - - BigInt big_rand; - big_rand.value = ""; // clear value to append digits - - // ensure that the first digit is non-zero - big_rand.value += std::to_string(1 + rand_generator() % 9); + num_digits = length_distribution(gen); + // insert other digits while (big_rand.value.size() < num_digits) - big_rand.value += std::to_string(rand_generator()); - if (big_rand.value.size() != num_digits) - big_rand.value.erase(num_digits); // erase extra digits + big_rand.value += std::to_string(digit_distr(gen)); return big_rand; } - #endif // BIG_INT_RANDOM_FUNCTIONS_HPP