diff --git a/README.md b/README.md
index 983df01..64c9df2 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,6 @@
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