Форум программистов, компьютерный форум CyberForum.ru

std::random_device - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.90
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
17.11.2012, 19:02     std::random_device #1
Здравствуйте.
Я так понимаю, Windows, в отличии от линя, не предоставляет специльное устройство для недетерминированных случайных чисел. Т.е. запись
C++
1
std::random_device rd;
под виндой ругается и кидает ексепшн. Неужели ф-ция из стандартной библиотеки писалась лишь для использования под никсы ? (приятно конечно, но лишь отчасти)
Как на винде то получить недетерминированное число, или прийдется довольствоваться следующей записью ?
C++
1
2
std::mt19937 gen;
gen.seed (time (0));
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
17.11.2012, 19:12     std::random_device #2
Цитата Сообщение от MrGluck Посмотреть сообщение
Неужели ф-ция из стандартной библиотеки писалась лишь для использования под никсы ?
Все нормально работает и под виндой, ищи ошибку у себя. Было проверено в VS2012
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
17.11.2012, 19:28  [ТС]     std::random_device #3
[IMG]http://i47.***********/thumb/2012/1117/51/0bf492eff7e20ed90d7255f0eca99951.jpeg[/IMG]
Под линем все компилится без проблем. В CB компиль mingw (gcc 4.7.0).
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
17.11.2012, 19:34     std::random_device #4
Цитата Сообщение от MrGluck Посмотреть сообщение
Под линем все компилится без проблем. В CB компиль mingw (gcc 4.7.0).
Ну зашибись, у меня под виндой тоже все компилится без проблем. Тогда в чем проблема? И при чем ты тут вообще вспомнил про винду? Напиши разработчикам компилятора.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
17.11.2012, 19:41  [ТС]     std::random_device #5
Vourhey, проблема в том, чтобы получить на винде доступ к специальному устройству.
Я так понял, что сделать нельзя, исходя из этого
Note: Some operating systems abstract the computer hardware enough to make it difficult to non-intrusively monitor stochastic processes. However, several do provide a special device for exactly this purpose. It seems to be impossible to emulate the functionality using Standard C++ only, so users should be aware that this class may not be available on all platforms.
Источник: http://www.solarix.ru/for_developers...t_random.shtml
Я прошу помочь сделать это на винде, а не показать, насколько плохая/хорошая ОС или компилятор.
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
17.11.2012, 19:44     std::random_device #6
std::random_device
Значит, это может работать в винде и без эксепшнов.
Значит, нужно узнать, что за код создает твой компилер. Хотя, бы дизассемблировать и узнать, где эксепшн возникает. Или в рантайме посмотреть, в каком вызове падает.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
17.11.2012, 21:55  [ТС]     std::random_device #7
Vourhey,
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
6FCFE830    push   %rbx
6FCFE831    sub    $0x20,%rsp
6FCFE835    mov    0xb974(%rip),%rax        # 0x6fd0a1b0 <libstdc++-6!_ZN10__cxxabiv120__unexpected_handlerE>
6FCFE83C    lea    -0x20(%rcx),%rbx
6FCFE840    mov    %rdx,-0x70(%rcx)
6FCFE844    mov    %r8,-0x68(%rcx)
6FCFE848    movl   $0x1,-0x80(%rcx)
6FCFE84F    mov    %rax,-0x60(%rcx)
6FCFE853    mov    0xb946(%rip),%rax        # 0x6fd0a1a0 <libstdc++-6!_ZN10__cxxabiv119__terminate_handlerE>
6FCFE85A    mov    %rax,-0x58(%rcx)
6FCFE85E    movabs $0x474e5543432b2b00,%rax
6FCFE868    mov    %rax,-0x20(%rcx)
6FCFE86C    lea    -0x9f9b3(%rip),%rax        # 0x6fc5eec0 <libstdc++-6!__gcclibcxx_demangle_callback+68624>
6FCFE873    mov    %rax,-0x18(%rcx)
6FCFE877    mov    %rbx,%rcx
6FCFE87A    callq  0x6fc4f9c0 <libstdc++-6!__gcclibcxx_demangle_callback+5904>
6FCFE87F    mov    %rbx,%rcx
6FCFE882    callq  0x6fcfdc40 <libstdc++-6!__cxa_begin_catch>
6FCFE887    callq  0x6fcf54f0 <libstdc++-6!_ZSt9terminatev>
6FCFE88C    nop
6FCFE88D    nop
6FCFE88E    nop
6FCFE88F    nop
падает точно при попытке создать std::random_device. (экспешн кидается при вызове explicit random_device(const std::string& token = default_token) )

The pseudo-device should never signal an error or end-of-file. Otherwise, std::ios_base::failure is thrown.
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
18.11.2012, 01:42     std::random_device #8
Цитата Сообщение от MrGluck Посмотреть сообщение
точно при попытке создать std::random_device
Ну значит где-то в стандартной библиотеке. "Обратитесь к поставщику" Хотя, хз, на 8-ке проверял, не знаю, как на 7-ке себя поведет.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
18.11.2012, 01:45     std::random_device #9
MrGluck, не приходило в голову что это просто заглушка с исключением, а сам std::random_device ещё не реализован в этой версии mingw.
юзай бустовый
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
18.11.2012, 01:51  [ТС]     std::random_device #10
Цитата Сообщение от Vourhey Посмотреть сообщение
Ну значит где-то в стандартной библиотеке. "Обратитесь к поставщику" Хотя, хз, на 8-ке проверял, не знаю, как на 7-ке себя поведет.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class random_device
  {
  public:
    // types
    typedef unsigned int result_type;
 
    // constructors, destructors and member functions
 
#ifdef _GLIBCXX_USE_RANDOM_TR1
 
    explicit
    random_device(const std::string& __token = "/dev/urandom")
    {
      if ((__token != "/dev/urandom" && __token != "/dev/random")
      || !(_M_file = std::fopen(__token.c_str(), "rb")))
    std::__throw_runtime_error(__N("random_device::"
                       "random_device(const std::string&)"));
    }
    ...
а у вас?
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
18.11.2012, 02:14     std::random_device #11
Проверил то же самое приложение, код которого на картинке. И в семерке все работает окей.

Странный код
Цитата Сообщение от MrGluck Посмотреть сообщение
if ((__token != "/dev/urandom" && __token != "/dev/random")
* * * || !(_M_file = std::fopen(__token.c_str(), "rb")))
не понимаю, какого фига он на винде пытается открыть /dev/urandom? Это же никсовый девайс Они библиотеку что ли не портировали?

Добавлено через 5 минут
Судя по коду, тут удивляться больше нечему. /dev/urandom на винде нет. Логично, что он его открыть не может. Это, от никсовой версии, похоже, и осталось при переносе библиотеки.
А стандартная библиотека от MS работает нормально, как и ожидается, потому что не пытается открывать несуществующих девайсов виртуальных.

Добавлено через 4 минуты
Я убрал портянку MS-кого кода, потому что она тут и не нужна, и так вроде видно, что трабла в стандартной либе, поставляющейся с тем компилятором или средой, что ты используешь.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
18.11.2012, 02:24  [ТС]     std::random_device #12
Vourhey, вот в том то и дело, что в MinGW random.h осталась от родного gcc) Как раз, как опубликовал пост с описанием конструктора, так и понял. Думал, мб в качестве параметра конструктора можно будет путь к спец. устройству передать (MS_DEF_PROV на винде). Прийдется ставить буст и менять файл random.h.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
18.11.2012, 02:34     std::random_device #13
а зачем ты делаешь (охренительно конечно, что ты не мог вставить код)
C++
1
std::mt19937 gen(rd());
а не
C++
1
std::mt19937 gen(rd);
хотя тут видимо до этого кода дело не доходит
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
18.11.2012, 02:44  [ТС]     std::random_device #14
Цитата Сообщение от alex_x_x Посмотреть сообщение
а зачем ты делаешь (охренительно конечно, что ты не мог вставить код)
C++
1
std::mt19937 gen(rd());
а не
C++
1
std::mt19937 gen(rd);
хотя тут видимо до этого кода дело не доходит
Потому, что в твоем случае
Код
error: 'class std::random_device' has no member named 'generate'|
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
18.11.2012, 02:53     std::random_device #15
ok, я посмотрел в описание и удивлен еще больше
что ты делаешь:
ты создаешь std::random_device
std::random_device равномерно распределенных целых генератор случайных чисел, который производит истинно случайных чисел, если недетерминированных источников (например, аппаратное устройство) доступен для реализации.
для того чтобы (sic!) инициализировать другой генератор случайных чисел
rd() - генерирует псевдослучайное число, которое используется для инициализации второго генератора
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
18.11.2012, 03:25  [ТС]     std::random_device #16
Цитата Сообщение от alex_x_x Посмотреть сообщение
ok, я посмотрел в описание и удивлен еще больше
что ты делаешь:
ты создаешь std::random_device

для того чтобы (sic!) инициализировать другой генератор случайных чисел
rd() - генерирует псевдослучайное число, которое используется для инициализации второго генератора
Ну да, а также можно инициализировать gen.seed (time (0)). Оно берет число, отталкиваясь от которого генерирует случайные числа, если брать константу, то будет генерировать уже не псевдослучайные числа, а каждый раз показывать одинаковый результат. Нам не нужно использовать всю мощь random_device, нам хватит взять лишь одно недетерменированное число, а на основе него уже создавать другие случайные числа.

Добавлено через 4 минуты
Генератор СЧ нужно же как то инициализировать. Почему вас смущает тот факт, что инициализировать будет результат другого ГСЧ, недетерменированного. На srand (time (0)) никто не орет, хотя принцип действия тот же.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
18.11.2012, 03:30     std::random_device #17
понимаешь в чем соль - для инициализации ПГСЧ нужно всего лишь уникальное число
использовать для инициализации ПГСЧ генератор более случайных чисел (грубо говоря) накладно и бессмысленно
тем более такой может быть и не реализован

хотя я вижу подобный пример на том же cppreference.com, но все же мне кажется это неправильно

Добавлено через 1 минуту
Цитата Сообщение от MrGluck Посмотреть сообщение
Почему вас смущает тот факт, что инициализировать будет результат другого ГСЧ, недетерменированного. На srand (time (0)) никто не орет, хотя принцип действия тот же.
Потому что это бессмысленно

из этой вашей википедии

на свойства последовательности псевдо случайных чисел влияет уникальность инициализатора, а не его природа
time(0) в-принципе достаточно уникален, так что все норм

из этой вашей википедии
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <boost/random.hpp>
#include <ctime>
 
using namespace boost;
 
double SampleNormal (double mean, double sigma)
{
    // выбор генератора случайных чисел
    mt19937 rng;
    // инициализация генератора числом секунд с 1970 года
    rng.seed(static_cast<unsigned> (std::time(0)));
 
    // выбор нужного распределения
    normal_distribution<double> norm_dist(mean, sigma);
 
    // привязка генератора к распределению
    variate_generator<mt19937&, normal_distribution<double> >  normal_sampler(rng, norm_dist);
 
    // пример работы
    return normal_sampler();
}
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,404
18.11.2012, 03:49  [ТС]     std::random_device #18
alex_x_x, да, есть возможность обойтись без этого, но использование ГСЧ для инициализации добавляет ++ к "случайности". Оно, естественно не делает ГПСЧ ГСЧ (понятно, что истинного ГСЧ не существует, но иначе получилась бы каша в терминах), но начало распределения уже становится неслучайным. Чем инициализировать, все же, по-моему, остается делом вкуса, но думаю не нужно спорить о том, что случайности time(0) может не хватать.

P.S. именно оттуда я и взял способ инициализации, но тогда я не ставил это под сомнение, а принял как данность.
soon
 Аватар для soon
2536 / 1301 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
18.11.2012, 09:07     std::random_device #19
C++
1
2
3
4
5
6
7
#include <random>
 
int main()
{
    std::mt19937(std::random_device().operator()());
    return 0;
}
Как-то фигово выглядит.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2012, 09:17     std::random_device
Еще ссылки по теме:

C++ что использовать std::cout или просто using namespace std?
C++ std::random_device падает приложение
Как искать по std::vecotr из std::pait по одному значению из пары? C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
18.11.2012, 09:17     std::random_device #20
Цитата Сообщение от MrGluck Посмотреть сообщение
понятно, что истинного ГСЧ не существует
Ну как же не существует, когда random_device - это он и есть.
Yandex
Объявления
18.11.2012, 09:17     std::random_device
Ответ Создать тему

Метки
mingw, random_device
Опции темы

Текущее время: 14:54. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru