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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.90
MrGluck
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
#1

std::random_device - C++

17.11.2012, 19:02. Просмотров 4063. Ответов 37

Здравствуйте.
Я так понимаю, Windows, в отличии от линя, не предоставляет специльное устройство для недетерминированных случайных чисел. Т.е. запись
C++
1
std::random_device rd;
под виндой ругается и кидает ексепшн. Неужели ф-ция из стандартной библиотеки писалась лишь для использования под никсы ? (приятно конечно, но лишь отчасти)
Как на винде то получить недетерминированное число, или прийдется довольствоваться следующей записью ?
C++
1
2
std::mt19937 gen;
gen.seed (time (0));
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.11.2012, 19:02     std::random_device
Посмотрите здесь:

std::random_device падает приложение - C++
win7, gcc 4.4.7 пишет, ошибка "std::runtime_error" чего ему надо? Добавлено через 14 часов 17 минут вверх

Std::mutex и std::recursive_mutex - C++
Есть некий класс: class A { public bool some_method(); private: std::mutex mutex_;

Std::atomic vs std::mutex - C++
class AtomicSome { private: std::atomic_bool _isReady; //not std::atomic_flag public: ...

std::sort + std::lower_bound - C++
тема такая: есть класс person: class Person{ private: string name_; string adress_; long phone_; есть вектор объектов...

Ошибка terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc - C++
Есть задача: Написать программу, которая считывает текст из файла и выводит его на экран, заменив цифры от 0 до 9 на слова "ноль",...

Ошибка terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc - C++
Добрый день!Работаю с графами,и при больших значениях столкнулся с проблемой:ошибка в тесте программы на сайте такова: terminate called...

std::endl; и std::cout"/n"; - одно и то же? - C++
Весь вопрос в теме.... std::endl; и std::cout<<"/n"; - одно и то же?

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
17.11.2012, 19:12     std::random_device #2
Цитата Сообщение от MrGluck Посмотреть сообщение
Неужели ф-ция из стандартной библиотеки писалась лишь для использования под никсы ?
Все нормально работает и под виндой, ищи ошибку у себя. Было проверено в VS2012
MrGluck
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
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
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
17.11.2012, 19:34     std::random_device #4
Цитата Сообщение от MrGluck Посмотреть сообщение
Под линем все компилится без проблем. В CB компиль mingw (gcc 4.7.0).
Ну зашибись, у меня под виндой тоже все компилится без проблем. Тогда в чем проблема? И при чем ты тут вообще вспомнил про винду? Напиши разработчикам компилятора.
MrGluck
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
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
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
17.11.2012, 19:44     std::random_device #6
std::random_device
Значит, это может работать в винде и без эксепшнов.
Значит, нужно узнать, что за код создает твой компилер. Хотя, бы дизассемблировать и узнать, где эксепшн возникает. Или в рантайме посмотреть, в каком вызове падает.
MrGluck
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
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
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
18.11.2012, 01:42     std::random_device #8
Цитата Сообщение от MrGluck Посмотреть сообщение
точно при попытке создать std::random_device
Ну значит где-то в стандартной библиотеке. "Обратитесь к поставщику" Хотя, хз, на 8-ке проверял, не знаю, как на 7-ке себя поведет.
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
18.11.2012, 01:45     std::random_device #9
MrGluck, не приходило в голову что это просто заглушка с исключением, а сам std::random_device ещё не реализован в этой версии mingw.
юзай бустовый
MrGluck
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
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
Почетный модератор
6474 / 2249 / 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
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
18.11.2012, 02:24  [ТС]     std::random_device #12
Vourhey, вот в том то и дело, что в MinGW random.h осталась от родного gcc) Как раз, как опубликовал пост с описанием конструктора, так и понял. Думал, мб в качестве параметра конструктора можно будет путь к спец. устройству передать (MS_DEF_PROV на винде). Прийдется ставить буст и менять файл random.h.
alex_x_x
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
18.11.2012, 02:34     std::random_device #13
а зачем ты делаешь (охренительно конечно, что ты не мог вставить код)
C++
1
std::mt19937 gen(rd());
а не
C++
1
std::mt19937 gen(rd);
хотя тут видимо до этого кода дело не доходит
MrGluck
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
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
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
18.11.2012, 02:53     std::random_device #15
ok, я посмотрел в описание и удивлен еще больше
что ты делаешь:
ты создаешь std::random_device
std::random_device равномерно распределенных целых генератор случайных чисел, который производит истинно случайных чисел, если недетерминированных источников (например, аппаратное устройство) доступен для реализации.
для того чтобы (sic!) инициализировать другой генератор случайных чисел
rd() - генерирует псевдослучайное число, которое используется для инициализации второго генератора
MrGluck
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
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
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
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
Модератор
Эксперт CЭксперт С++
6960 / 4131 / 586
Регистрация: 29.11.2010
Сообщений: 10,956
18.11.2012, 03:49  [ТС]     std::random_device #18
alex_x_x, да, есть возможность обойтись без этого, но использование ГСЧ для инициализации добавляет ++ к "случайности". Оно, естественно не делает ГПСЧ ГСЧ (понятно, что истинного ГСЧ не существует, но иначе получилась бы каша в терминах), но начало распределения уже становится неслучайным. Чем инициализировать, все же, по-моему, остается делом вкуса, но думаю не нужно спорить о том, что случайности time(0) может не хватать.

P.S. именно оттуда я и взял способ инициализации, но тогда я не ставил это под сомнение, а принял как данность.
soon
2538 / 1303 / 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
Еще ссылки по теме:

Как кинуть исключение std::locale::global(std::locale(""); - C++
Добрый день. Знаю, что на С можно так: if (!setlocale(LC_ALL, &quot;&quot;)) { perror(&quot;Couldn't set locale&quot;); exit(EXIT_FAILURE); }...

std::ios::hex или std::ios.hex - C++
привет в коде встретил вот такую строчку ss.setf(std::ios.hex, std::ios::basefield); и на VS2008 это работает. Разве это...

std::basic_istream<_CharT, _Traits>::basic_istream() [with _CharT = char; _Traits = std::char_traits<char>]» is protected - C++
Есть класс: class Expression { public: Expression(string expr, ErrorCallback errcb=0); Expression(const Expression&amp; orig); ...

std:: - C++
Объясните пожалуйста что это за тип? иногда им описывают переменную например std::x, если можно ссылку скиньте с подробным описанием

std - C++
Здрасти, как корректнее писать: 1) using namespace std string s; или 2) std::string s;


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru