Skip to content

Commit

Permalink
Improve calculations in random long
Browse files Browse the repository at this point in the history
  • Loading branch information
vorotynsky committed Aug 27, 2020
1 parent 3088738 commit 0441e69
Showing 1 changed file with 29 additions and 17 deletions.
46 changes: 29 additions & 17 deletions src/libraries/System.Private.CoreLib/src/System/Random.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,16 +222,10 @@ private long FullLong()
{
long result = 0;

for (int i = 0; i < 4; i++)
for (int i = 0; i < 8; i++)
{
short part;
unchecked
{
part = (short) InternalSample();
}

result |= (long) part;
result <<= 16;
result |= (long) (0xff & InternalSample());
result <<= 8;
}

return result;
Expand All @@ -244,7 +238,10 @@ private long FullLong()
==============================================================================*/
public virtual long NextInt64()
{
return FullLong();
long result = Math.Abs(FullLong());
if (result == long.MaxValue)
return 0;
return result;
}

/*==================================NextInt64===================================
Expand All @@ -260,9 +257,15 @@ public virtual long NextInt64(long maxValue)
if (maxValue == 0)
return 0;

long fullLong = (long) FullLong();
return (long.MaxValue & fullLong) % maxValue;
}
long result;
long range = (long.MaxValue - 1) - (long.MaxValue - 1) % maxValue;
do
{
result = NextInt64();
} while (result >= range);

return result % maxValue;
}

/*==================================NextInt64===================================
**Returns: A long [minvalue..maxvalue)
Expand All @@ -277,11 +280,20 @@ public virtual long NextInt64(long minValue, long maxValue)
throw new ArgumentOutOfRangeException(nameof(minValue), SR.Format(SR.Argument_MinMaxValue, nameof(minValue), nameof(maxValue)));
}

if (minValue == 0)
return NextInt64(maxValue);

if (minValue < 0 && maxValue > 0)
{
long minHalf = -NextInt64(-minValue);
long maxHalf = NextInt64(maxValue);

return minHalf + maxHalf;
}

long range = maxValue - minValue;
long range1 = range / 2;
long range2 = range - range1;

return NextInt64(range1 + 1) + NextInt64(range2) + minValue;
return NextInt64(range) + minValue;
}

/*==================================NextDouble==================================
Expand All @@ -301,7 +313,7 @@ public virtual double NextDouble()
==============================================================================*/
public virtual float NextSingle()
{
return (float) Sample();
return InternalSample() * (1.0f / MBIG);
}

/*==================================NextBytes===================================
Expand Down

0 comments on commit 0441e69

Please sign in to comment.