From f33363c6b8fd7c3843efc9772f7e296ba07ff189 Mon Sep 17 00:00:00 2001
From: B1Z0N
Date: Thu, 22 Aug 2019 15:47:05 +0300
Subject: [PATCH 1/5] Updated big_random function to use mersenne twister
---
include/functions/random.hpp | 40 ++++++++++++++++++++++++------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/include/functions/random.hpp b/include/functions/random.hpp
index 10d08cc..82cf8e3 100644
--- a/include/functions/random.hpp
+++ b/include/functions/random.hpp
@@ -24,25 +24,39 @@ const size_t MAX_RANDOM_LENGTH = 1000;
*/
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};
+ static std::uniform_int_distribution<> digit_distr(0, 9);
+ static std::uniform_int_distribution<> first_digit_distr(-9, 9);
+ // number to generate
+ static BigInt big_rand;
+
+ 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
+ num_digits = 1 + gen() % MAX_RANDOM_LENGTH;
+ }
- // ensure that the first digit is non-zero
- big_rand.value += std::to_string(1 + rand_generator() % 9);
+ // first digit and sign
+ auto first_digit = first_digit_distr(gen);
+ big_rand.value = std::to_string(abs(first_digit));
+ big_rand.sign = first_digit < 0 ? '-' : '+';
+ // 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
From 4932e30188d7ae12df1b34bda612b8d526cd648c Mon Sep 17 00:00:00 2001
From: B1Z0N
Date: Thu, 22 Aug 2019 15:48:12 +0300
Subject: [PATCH 2/5] Updated big_random tests to support new version of this
function
---
test/functions/random.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/test/functions/random.cpp b/test/functions/random.cpp
index 3d7b113..e6d50ae 100644
--- a/test/functions/random.cpp
+++ b/test/functions/random.cpp
@@ -5,6 +5,10 @@
#include "functions/random.hpp"
#include "operators/io_stream.hpp"
+// for abs
+#include "functions/math.hpp"
+#include "operators/binary_arithmetic.hpp"
+
#include "third_party/catch.hpp"
@@ -19,6 +23,6 @@ TEST_CASE("Generate random BigInts having a specified number of digits",
size_t num_digits;
for (int i = 0; i < 50; i++) {
num_digits = rand_generator() % 10000;
- REQUIRE(big_random(num_digits).to_string().size() == num_digits);
+ REQUIRE(abs(big_random(num_digits)).to_string().size() == num_digits);
}
}
From d99b98fc2bed75f82a3a0ce2e2b0111302a788ba Mon Sep 17 00:00:00 2001
From: B1Z0N
Date: Thu, 22 Aug 2019 16:07:25 +0300
Subject: [PATCH 3/5] Added right description for big_int function, and some
distributions Returned positive number generation, that was removed due to
misconception
---
include/functions/random.hpp | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/include/functions/random.hpp b/include/functions/random.hpp
index 82cf8e3..cfda809 100644
--- a/include/functions/random.hpp
+++ b/include/functions/random.hpp
@@ -20,7 +20,7 @@ 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) {
@@ -36,25 +36,24 @@ BigInt big_random(size_t num_digits = 0) {
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(-9, 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;
- if (num_digits == 0) {
+ // 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 + gen() % MAX_RANDOM_LENGTH;
- }
-
- // first digit and sign
- auto first_digit = first_digit_distr(gen);
- big_rand.value = std::to_string(abs(first_digit));
- big_rand.sign = first_digit < 0 ? '-' : '+';
+ num_digits = length_distribution(gen);
// insert other digits
while (big_rand.value.size() < num_digits)
- big_rand.value += std::to_string(digit_distr(gen));
+ big_rand.value += std::to_string(digit_distr(gen));
return big_rand;
}
From b10f0d84681c38b1b8aee71ec79cbacaa7222e4d Mon Sep 17 00:00:00 2001
From: B1Z0N
Date: Thu, 22 Aug 2019 16:07:57 +0300
Subject: [PATCH 4/5] Returned previouse state of tests, all passed
---
test/functions/random.cpp | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/test/functions/random.cpp b/test/functions/random.cpp
index e6d50ae..3d7b113 100644
--- a/test/functions/random.cpp
+++ b/test/functions/random.cpp
@@ -5,10 +5,6 @@
#include "functions/random.hpp"
#include "operators/io_stream.hpp"
-// for abs
-#include "functions/math.hpp"
-#include "operators/binary_arithmetic.hpp"
-
#include "third_party/catch.hpp"
@@ -23,6 +19,6 @@ TEST_CASE("Generate random BigInts having a specified number of digits",
size_t num_digits;
for (int i = 0; i < 50; i++) {
num_digits = rand_generator() % 10000;
- REQUIRE(abs(big_random(num_digits)).to_string().size() == num_digits);
+ REQUIRE(big_random(num_digits).to_string().size() == num_digits);
}
}
From 8dc5c8ed33c318685445e3aea1a397b75c847105 Mon Sep 17 00:00:00 2001
From: B1Z0N
Date: Thu, 22 Aug 2019 16:12:32 +0300
Subject: [PATCH 5/5] Fixed big_random description
---
README.md | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
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);
```