Exemple #1
0
        /// <summary>
        /// LCG constructor.
        /// <para>It is possible to define a randMax value less than or equal to m-1, as used by
        /// Rand48Lcg. Setting m to 0 negates the modulus.</para>
        /// </summary>
        /// <param name="randMax">Maximum value returned by Next()</param>
        /// <param name="a">Multiplier</param>
        /// <param name="c">Increment</param>
        /// <param name="m">Modulus</param>
        public LcgRng(ulong randMax, ulong a, ulong c, ulong m)
            : base(randMax)
        {
            if (m != 0 && m <= randMax)
            {
                throw new ArgumentException("randMax", "The RandMax value " + randMax +
                                            "is invalid (not possible with modulus " + m + ").");
            }

            mult = a;
            inc  = c;
            mod  = m;

            // Determine a bit mask to use instead of modulus, if possible.
            // This yields as big performance improvement as the C# "%" operator
            // does not appear optimized where the maximum result is a power of 2 value.

            // Default where modulus is 0,
            // which implicitly means 2^64.
            modMask = UInt64.MaxValue;

            if (mod != 0)
            {
                modMask = mod - 1;

                // Number of bits needed by modulus
                int mbits = CleromUtil.BitSize(modMask);

                // If not equal, we can't use a mask.
                if (modMask != UInt64.MaxValue >> (64 - mbits))
                {
                    modMask = 0;
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Subclasses must supply 'randMax', the maximum possible value returned by the
        /// implementation of the Next() method.
        /// </summary>
        /// <param name="randMax">Maximum value returned by Next()</param>
        public Rng(ulong randMax)
        {
            if (randMax == 0)
            {
                throw new ArgumentException("randMax", "RandMax cannot be zero!");
            }

            // Set read-only values
            nativeMax = randMax;
            native64  = (randMax == UInt64.MaxValue);
            native32  = (randMax == UInt32.MaxValue);

            // Get number of bits to use from Next().
            // A RandMax of 2^31-1 gives us 31.
            shiftBits = CleromUtil.BitSize(randMax);
            shiftMax  = UInt64.MaxValue >> (64 - shiftBits);

            if (randMax != shiftMax)
            {
                --shiftBits;
                shiftMax >>= 1;
            }

            // Initialize cache values
            ResetCache();

            // Useful for confirming properties when debugging

            /*
             * Console.WriteLine();
             * Console.WriteLine("NAME       : " + AlgorithmName);
             * Console.WriteLine("RandMax    : " + randMax);
             * Console.WriteLine("RandMax    : 0x" + randMax.ToString("X16"));
             * Console.WriteLine("Native32   : " + native32);
             * Console.WriteLine("Native64   : " + native64);
             * Console.WriteLine("BitShift  : " + shiftBits);
             * Console.WriteLine();
             */
        }