You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2019/08/07 22:26:20 UTC
[lucenenet] 23/42: BUG:
Lucene.Net.TestFramework.Util.TestUtil.NextLong: The result of the method
was always the value of start when start == long.MinValue and end ==
long.MaxValue. As a result, many tests were not actually random.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit 8d3636e1da707b34fbb1fad05fee217ae0e335ea
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sun Aug 4 02:43:30 2019 +0700
BUG: Lucene.Net.TestFramework.Util.TestUtil.NextLong: The result of the method was always the value of start when start == long.MinValue and end == long.MaxValue. As a result, many tests were not actually random.
---
src/Lucene.Net.TestFramework/Util/TestUtil.cs | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/src/Lucene.Net.TestFramework/Util/TestUtil.cs b/src/Lucene.Net.TestFramework/Util/TestUtil.cs
index 011e6c9..5a804d5 100644
--- a/src/Lucene.Net.TestFramework/Util/TestUtil.cs
+++ b/src/Lucene.Net.TestFramework/Util/TestUtil.cs
@@ -288,8 +288,31 @@ namespace Lucene.Net.Util
else
{
// probably not evenly distributed when range is large, but OK for tests
- BigInteger augend = new BigInteger(end + 1 - start) * (BigInteger)(r.NextDouble());
- long result = start + (long)augend;
+ //BigInteger augend = BigInteger.Multiply(range, new BigInteger(r.NextDouble()));
+ //long result = start + (long)augend;
+
+ // LUCENENET NOTE: Using BigInteger/Decimal doesn't work because r.NextDouble() is always
+ // rounded down to 0, which makes the result always the same as start. This alternative solution was
+ // snagged from https://stackoverflow.com/a/13095144. All we really care about here is that we get
+ // a pretty good random distribution of values between start and end.
+
+ //Working with ulong so that modulo works correctly with values > long.MaxValue
+ ulong uRange = (ulong)unchecked(end - start);
+
+ //Prevent a modolo bias; see https://stackoverflow.com/a/10984975/238419
+ //for more information.
+ //In the worst case, the expected number of calls is 2 (though usually it's
+ //much closer to 1) so this loop doesn't really hurt performance at all.
+ ulong ulongRand;
+ do
+ {
+ byte[] buf = new byte[8];
+ r.NextBytes(buf);
+ ulongRand = (ulong)BitConverter.ToInt64(buf, 0);
+ } while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange);
+
+ long result = (long)(ulongRand % uRange) + start + r.Next(0, 1); // Randomly decide whether to increment by 1 to make the second parameter "inclusive"
+
Assert.True(result >= start);
Assert.True(result <= end);
return result;