Method availability is not a “C# version” thing, it’s dependent on which BCL is available to use, which is linked to the overall version of the framework. And no, the API isn’t in the BCL/API profiles Unity advertises as shipping (.NET Standard 2.1 or .NET Framework 4.8 + .NET Standard 2.1). All signs point to waiting for the .NET modernization to come to fruition. Fingers crossed for Unite to have something interesting to share on that front.
You could take responsibility and actually show yourself experimenting with running your experimental code instead of just theorycrafting.
Here’s my suggestion, since looping and plain branching leaves a bad taste in my mouth for the math package.
static float NextFloatExclusiveMax(this ref Random random, float min, float max)
{
float initialResult = random.NextFloat() * (max - min) + min;
return math.clamp(initialResult, min, math.max(min, MathF.BitDecrement(max));
}
Usable implementation in any recent .NET:
using System.Diagnostics;
ValidateBounds(0, 0);
ValidateBounds(1, 1);
ValidateBounds(2024, 2024);
ValidateBounds(0, 1);
ValidateBounds(1, 1.5f);
ValidateBounds(1, 5);
ValidateBounds(117, 343);
ValidateBounds(3348, 39014.36f);
ValidateBounds(9999, 999999999999);
static float NextFloat(float v, float min, float max)
{
float initialResult = v * (max - min) + min;
return Math.Clamp(initialResult, min, Math.Max(min, MathF.BitDecrement(max)));
}
static void ValidateBounds(float min, float max)
{
const float vMin = 0;
const float vMax = 0.99999988079071044921875f;
float fMin = NextFloat(vMin, min, max);
float fMax = NextFloat(vMax, min, max);
if (min.Equals(max))
{
Debug.Assert(fMin.Equals(min));
Debug.Assert(fMax.Equals(min));
}
else
{
Debug.Assert(fMin >= min);
Debug.Assert(fMin < max);
Debug.Assert(fMax >= min);
Debug.Assert(fMax < max);
}
}
I see this as a dead end overall, as my suspicion continues to be that they would rather not change established behavior, considering they care about determinism to some degree.