Генератор Случайных Чисел Класс


Я написал абстрактный класс В C# для генерации случайных чисел из массива байт. Интернет .Чистый класс RNGCryptoServiceProvider может быть использован для создания массива случайных байт, например.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyLibrary
{
    /// <summary>
    /// Represents the abstract base class for a random number generator.
    /// </summary>
    public abstract class Rng
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Rng"/> class.
        /// </summary>
        public Rng()
        {
            //
        }

        public Int16 GetInt16(Int16 min, Int16 max)
        {
            return (Int16)(min + (Int16)(GetDouble() * (max - min)));
        }

        public Int32 GetInt32(Int32 min, Int32 max)
        {
            return (Int32)(min + (Int32)(GetDouble() * (max - min)));
        }

        public Int64 GetInt64(Int64 min, Int64 max)
        {
            return (Int64)(min + (Int64)(GetDouble() * (max - min)));
        }

        public UInt16 GetUInt16(UInt16 min, UInt16 max)
        {
            return (UInt16)(min + (UInt16)(GetDouble() * (max - min)));
        }

        public UInt32 GetUInt32(UInt32 min, UInt32 max)
        {
            return (UInt32)(min + (UInt32)(GetDouble() * (max - min)));
        }

        public UInt64 GetUInt64(UInt64 min, UInt64 max)
        {
            return (UInt64)(min + (UInt64)(GetDouble() * (max - min)));
        }

        public Single GetSingle()
        {
            return (Single)GetUInt64() / UInt64.MaxValue;
        }

        public Double GetDouble()
        {
            return (Double)GetUInt64() / UInt64.MaxValue;
        }

        public Int16 GetInt16()
        {
            return BitConverter.ToInt16(GetBytes(2), 0);
        }

        public Int32 GetInt32()
        {
            return BitConverter.ToInt32(GetBytes(4), 0);
        }

        public Int64 GetInt64()
        {
            return BitConverter.ToInt64(GetBytes(8), 0);
        }

        public UInt16 GetUInt16()
        {
            return BitConverter.ToUInt16(GetBytes(2), 0);
        }

        public UInt32 GetUInt32()
        {
            return BitConverter.ToUInt32(GetBytes(4), 0);
        }

        public UInt64 GetUInt64()
        {
            return BitConverter.ToUInt64(GetBytes(8), 0);
        }

        /// <summary>
        /// Generates random bytes of the specified length.
        /// </summary>
        /// <param name="count">The number of bytes to generate.</param>
        /// <returns>The randomly generated bytes.</returns>
        public abstract byte[] GetBytes(int count);
    }
}

Любые предложения по улучшению будут приветствоваться.



2827
12
задан 2 февраля 2011 в 12:02 Источник Поделиться
Комментарии
3 ответа

Я думаю, что дизайн довольно хороший. Несколько замечаний:


  • Я бы переименовать этот класс В чем-то немного более описательное, скажем RandomGenerator. Затем, когда вы реализуете класс, который вы можете объявить его с CspGenerator: RandomGenerator или MersenneGenerator: RandomGenerator и очевидно, что этот класс делает.

  • Комментировать получить() методы. ИМО все общественные элементы должны быть задокументированы. Получить/установить можно, но это вопрос предпочтений. В частности, я хотел бы знать, какой диапазон мин и Макс и используется для.

  • Это метод getbytes() необходимы внешне? Если нет, я бы рассмотреть возможность сделать это на уровне класса, а не общественные.

Форматирование хорошо - даже в Visual студии, я видел, как он вляпается как код переработан и изменен.

8
ответ дан 2 февраля 2011 в 02:02 Источник Поделиться

Я думаю, что с помощью GetDouble для создания других случайных чисел может создать проблемы с производительностью, когда пользователь нуждается в эффективной случайных чисел.

Поскольку метод getbytes возвращает равномерное распределение в любом случае, вы не можете обойти, используя числа с плавающей точкой? См., например, для Java - случайный.nextInt реализации.

Что-то еще, но это может оказаться ненужным и YAGNI для вас: вы рассматривали разделение ГСЧ от функции плотности вероятности? На данный момент ваш ГСЧ напрямую поддерживает генерации равномерно распределенных чисел в заданном диапазоне – но он не поддерживает никакие другие дистрибутивы. Это может быть разгружен на отдельную распределение класса. Для справки, импульс.Случайный ли это.

6
ответ дан 2 февраля 2011 в 04:02 Источник Поделиться

Если вы планируете размещение в библиотеке повторного использования необходимо проверить входы (мин > макс бросает исключение indexoutofrangeexception и т. д.) Кроме того, вам не нужно приведение к Double в GetDouble способ, как разделение неявно возвращает значение типа double, и отливка первого операнда отдела в GetSingle до сих пор вызывает разделение будет возвращать в двойном размере хотя вы можете быть немного жертвуя точностью в рандоме в результате ущерба 32 бита, прежде чем делить.

В противном случае код выглядит так, как будто это было бы достаточно. В зависимости от объема вашего решения, возможно, нужно учитывать мин/макс перегрузок для GetSingle и GetDouble и если вы действительно хотите быть особенным, может быть, поддержка системы.Числа.BigInteger и системы.Десятичное?

3
ответ дан 2 февраля 2011 в 02:02 Источник Поделиться