Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.08.2016, 13:05   #1
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию Класс Random, зерно в конструкторе

Здравствуйте. Проблема такова: конструктор класса Random принимает зерно только параметром int (32 разряда). Где и как можно найти/сделать генератор, который принимает в качестве зерна число в 64 разряда (long) ?
Это вопрос уникальности выходных данных генератора, поэтому создавать костыли типа "разбить зерно на два 32 разрядных числа, и использовать два генератора ..." - не прокатит, ибо на какие нибудь два разных зерна будет одинаковый набор выходных данных.
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 28.08.2016, 13:16   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

может вам тогда заюзать крипторандом?
https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx
+ у нас есть исходники же, можно переделать, например так:
Код:
    public class LongRandom:Random
    {
        //
        // Private Constants 
        //
        private const long MBIG = long.MaxValue;
        private const long MSEED = 161803398;
        private const long MZ = 0;


        //
        // Member Variables
        //
        private long inext;
        private long inextp;
        private long[] SeedArray = new long[56];

        //
        // Public Constants
        //

        //
        // Native Declarations
        //

        //
        // Constructors
        //

        public LongRandom()
          : this(Environment.TickCount)
        {
        }

        public LongRandom(long Seed)
        {
            long ii;
            long mj, mk;

            //Initialize our Seed array.
            //This algorithm comes from Numerical Recipes in C (2nd Ed.)
            long subtraction = (Seed == long.MinValue) ? long.MaxValue : Math.Abs(Seed);
            mj = MSEED - subtraction;
            SeedArray[55] = mj;
            mk = 1;
            for (int i = 1; i < 55; i++)
            {  //Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position.
                ii = (21 * i) % 55;
                SeedArray[ii] = mk;
                mk = mj - mk;
                if (mk < 0) mk += MBIG;
                mj = SeedArray[ii];
            }
            for (int k = 1; k < 5; k++)
            {
                for (int i = 1; i < 56; i++)
                {
                    SeedArray[i] -= SeedArray[1 + (i + 30) % 55];
                    if (SeedArray[i] < 0) SeedArray[i] += MBIG;
                }
            }
            inext = 0;
            inextp = 21;
            Seed = 1;
        }
        protected override double Sample()
        {
            return (InternalSample() * (1.0 / MBIG));
        }
        private long InternalSample()
        {
            long retVal;
            long locINext = inext;
            long locINextp = inextp;

            if (++locINext >= 56) locINext = 1;
            if (++locINextp >= 56) locINextp = 1;

            retVal = SeedArray[locINext] - SeedArray[locINextp];

            if (retVal == MBIG) retVal--;
            if (retVal < 0) retVal += MBIG;

            SeedArray[locINext] = retVal;

            inext = locINext;
            inextp = locINextp;

            return retVal;
        }
        private double GetSampleForLargeRange()
        {
            // The distribution of double value returned by Sample 
            // is not distributed well enough for a large range.
            // If we use Sample for a range [Int32.MinValue..Int32.MaxValue)
            // We will end up getting even numbers only.

            long result = InternalSample();
            // Note we can't use addition here. The distribution will be bad if we do that.
            bool negative = (InternalSample() % 2 == 0) ? true : false;  // decide the sign based on second sample
            if (negative)
            {
                result = -result;
            }
            double d = result;
            d += (long.MaxValue - 1); // get a number in range [0 .. 2 * Int32MaxValue - 1)
            d /= 2 * (ulong)long.MaxValue - 1;
            return d;
        }
        public override int Next()
        {
            return (int)InternalSample();
        }
        public override int Next(int minValue, int maxValue)
        {
            long range = (long)maxValue - minValue;
            if (range <= (long)long.MaxValue)
            {
                return ((int)(Sample() * range) + minValue);
            }
            else
            {
                return (int)((long)(GetSampleForLargeRange() * range) + minValue);
            }
        }
        public long NextLong()
        {
            return InternalSample();
        }
        public long NextLong(long minValue, long maxValue)
        {
            long range = (long)maxValue - minValue;
            if (range <= (long)long.MaxValue)
            {
                return ((long)(Sample() * range) + minValue);
            }
            else
            {
                return ((long)(GetSampleForLargeRange() * range) + minValue);
            }
        }
        public long NextLong(long maxValue)
        {
            return (long)(Sample() * maxValue);
        }
        public override void NextBytes(byte[] buffer)
        {
            if (buffer == null) throw new ArgumentNullException("buffer");
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = (byte)(InternalSample() % (Byte.MaxValue + 1));
            }
        }
    }
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 28.08.2016 в 13:30.
Пепел Феникса вне форума Ответить с цитированием
Старый 28.08.2016, 18:29   #3
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Пепел Феникса
А где можно нарыть исходники этого фреймворка, который под WinForms ?
Это мне интересно, и не только для рандома ...
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 28.08.2016, 18:39   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Random не является ни частью WinForms, ни WPF, ни прочего.
http://referencesource.microsoft.com...stem/random.cs
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ТРИ ГОЛОВЫ ЗМЕЯ ГОРЫНЫЧА – ЗЕРНО, РЕЛИГИЯ, АЛКОГОЛЬ антигерой Свободное общение 12 23.04.2013 13:11
Класс запускает поток, который заполняет этот класс. Обмен класс <=> поток. Человек_Борща Общие вопросы Delphi 8 27.02.2012 23:24
Задача про зерно _Aptem_ Общие вопросы C/C++ 19 16.07.2011 12:04
ошибка в конструкторе C++ Ver0nica Помощь студентам 1 24.04.2011 13:34
класс Random Sergey_Zelenev C# (си шарп) 2 24.04.2011 00:45