csharp/EPAM.Deltix.DFP.Benchmark/RandomDecimalsGenerator.cs (83 lines of code) (raw):

using System; using System.Collections.Generic; using System.Text; namespace EPAM.Deltix.DFP.Benchmark { internal class RandomDecimalsGenerator { readonly Random generator; Decimal64 x = Decimal64.NaN; int xExp = 0; Decimal64 y = Decimal64.NaN; int yExp = 0; readonly int mantissaMaxShift; readonly int exponentRange; readonly int exponentOffset; private static readonly int TwiceOfMaxSignificandDigits = Decimal64.MaxSignificandDigits * 2; private static readonly int HalfOfMaxSignificandDigits = Decimal64.MaxSignificandDigits / 2; public RandomDecimalsGenerator() : this((int)DateTime.Now.Ticks) { } public RandomDecimalsGenerator(int randomSeed) : this(new Random(randomSeed), 1, -TwiceOfMaxSignificandDigits - HalfOfMaxSignificandDigits, TwiceOfMaxSignificandDigits - HalfOfMaxSignificandDigits) { } public RandomDecimalsGenerator( Random generator, int mantissaMinBits, int exponentMin, int exponentMax) { if (generator == null) throw new ArgumentException("The random argument is null."); if (mantissaMinBits < 1 || 64 < mantissaMinBits) throw new ArgumentException("The mantissaMinBits(=" + mantissaMinBits + ") must lie in [1..64] range"); if (exponentMin < Decimal64.MinExponent || Decimal64.MaxExponent < exponentMin) throw new ArgumentException("The exponentMin(=" + exponentMin + ") must lie in [" + Decimal64.MinExponent + ".." + Decimal64.MaxExponent + "] range."); if (exponentMax < Decimal64.MinExponent || Decimal64.MaxExponent < exponentMax) throw new ArgumentException("The exponentMax(=" + exponentMax + ") must lie in [" + Decimal64.MinExponent + ".." + Decimal64.MaxExponent + "] range."); if (exponentMax <= exponentMin) throw new ArgumentException("The exponentMin(=" + exponentMin + ") must be less than the exponentMax(=" + exponentMax + "."); this.generator = generator; this.mantissaMaxShift = 64 - mantissaMinBits + 1 /* for random.nextInt() exclusive upper bound */; this.exponentRange = exponentMax - exponentMin; this.exponentOffset = exponentMin; } public void MakeNextPair() { NextX(); NextY(); } private long NextLong() { return ((long)generator.Next(4) << 62) + ((long)generator.Next() << 31) + (long)generator.Next(); } public Decimal64 NextX() { xExp = generator.Next(exponentRange) + exponentOffset; return x = Decimal64.FromFixedPoint(NextLong() >> generator.Next(mantissaMaxShift), -xExp); } public Decimal64 NextY() { yExp = generator.Next(exponentRange) + exponentOffset; return y = Decimal64.FromFixedPoint(NextLong() >> generator.Next(mantissaMaxShift), -yExp); } public Decimal64 X => x; public int XExp => xExp; public Decimal64 Y => y; public int YExp => yExp; public override string ToString() { return "RandomDecimalsGenerator{" + "x=" + x.ToScientificString() + ", xExp=" + xExp + ", y=" + y.ToScientificString() + ", yExp=" + yExp + '}'; } } }