.NET
Random.Next()
programming
software development
statistical distribution

Adding an average parameter to .NET's Random.Next to curve results

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Random.Next() is uniform by design. Every integer in the requested range is equally likely, so you cannot add an "average" parameter to that method and still call the result a uniform random generator.

What you actually want is a different distribution. If results should cluster around a central value, you need a sampling method such as a normal-like, triangular, or custom weighted distribution and then map it into your target range.

Why an Average Parameter Is Not Enough

A mean alone does not define a distribution. Two random generators can share the same average while producing very different shapes:

  • one might be tightly concentrated near the center
  • one might have long tails
  • one might be triangular
  • one might be approximately normal

So the real design question is not "how do I add an average parameter?" It is "what distribution shape do I want?"

A Simple Curved Distribution

One easy way to bias values toward the center is to average several uniform draws. The more draws you average, the stronger the pull toward the mean.

csharp
1using System;
2
3public static class RandomExtensions
4{
5    public static int NextCentered(this Random random, int minValue, int maxValue, int samples = 3)
6    {
7        if (samples <= 0) throw new ArgumentOutOfRangeException(nameof(samples));
8
9        double total = 0;
10        for (int i = 0; i < samples; i++)
11        {
12            total += random.NextDouble();
13        }
14
15        double curved = total / samples;
16        return minValue + (int)(curved * (maxValue - minValue));
17    }
18}
19
20public static class Program
21{
22    public static void Main()
23    {
24        var random = new Random();
25
26        for (int i = 0; i < 10; i++)
27        {
28            Console.WriteLine(random.NextCentered(0, 100));
29        }
30    }
31}

This does not give a perfect Gaussian distribution, but it does create a center-heavy shape.

Choosing the Mean Explicitly

If you want the distribution centered around a chosen mean instead of the range midpoint, you need a more explicit model. A normal distribution is the usual choice.

The Box-Muller transform can generate approximately normal values:

csharp
1using System;
2
3public static class GaussianRandom
4{
5    public static double NextGaussian(this Random random, double mean, double stdDev)
6    {
7        double u1 = 1.0 - random.NextDouble();
8        double u2 = 1.0 - random.NextDouble();
9        double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
10                               Math.Sin(2.0 * Math.PI * u2);
11
12        return mean + stdDev * randStdNormal;
13    }
14}

If you then need an integer range, clamp or reject out-of-range values carefully.

Mapping to Integer Ranges

For bounded integer output, there are two common choices:

  • clamp out-of-range values back into bounds
  • resample until the value lands inside the bounds

Clamping is simple but distorts the edges. Resampling preserves the intended shape better but may do extra work if the range is narrow relative to the chosen standard deviation.

Pick the Distribution First

Use:

  • uniform when every outcome should be equally likely
  • triangular or averaged-uniform for simple center bias
  • Gaussian when you want a tunable mean and spread

That framing is more honest than trying to mutate Random.Next() into something it was never meant to represent.

Common Pitfalls

  • Asking for an average without defining the distribution shape.
  • Assuming a bounded normal distribution can be created by naive clamping without distortion.
  • Using the midpoint average-of-uniforms trick when the required mean is not the midpoint.
  • Forgetting that integers lose some precision from the underlying continuous sample.
  • Renaming a non-uniform generator as if it were still just Random.Next().

Summary

  • 'Random.Next() is uniform and should stay that way conceptually.'
  • A desired average implies you need a different distribution, not a small parameter tweak.
  • Averaging multiple uniform draws creates a simple center-biased curve.
  • Gaussian sampling is better when you need an explicit mean and spread.
  • Choose the distribution first, then map it carefully into your target integer range.

Course illustration
Course illustration

All Rights Reserved.