Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.90
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
#1

std::random_device - C++

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

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

Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream
Здравствуйте! Я хотел начать изучать язык C++. Набрал литературы. Установил...

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri
на вод поступают 2 строки типа string. определить количество вхождений строки 2...

STL std::set, std::pair, std::make_pair
Я не знаю как описать тему в двух словах, поэтому не обращайте внимание на...

На основе исходного std::vector<std::string> содержащего числа, создать std::vector<int> с этими же числами
подскажите есть вот такая задача. Есть список . Создать второй список, в...

Std::begin() ,std::end(),std::copy
...// int main() { std::vector&lt;double&gt; data;//Работает cout &lt;&lt;...

37
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
17.11.2012, 19:12 #2
Цитата Сообщение от MrGluck Посмотреть сообщение
Неужели ф-ция из стандартной библиотеки писалась лишь для использования под никсы ?
Все нормально работает и под виндой, ищи ошибку у себя. Было проверено в VS2012
0
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
17.11.2012, 19:28  [ТС] #3

Под линем все компилится без проблем. В CB компиль mingw (gcc 4.7.0).
0
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
17.11.2012, 19:34 #4
Цитата Сообщение от MrGluck Посмотреть сообщение
Под линем все компилится без проблем. В CB компиль mingw (gcc 4.7.0).
Ну зашибись, у меня под виндой тоже все компилится без проблем. Тогда в чем проблема? И при чем ты тут вообще вспомнил про винду? Напиши разработчикам компилятора.
0
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
17.11.2012, 19:41  [ТС] #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
Я прошу помочь сделать это на винде, а не показать, насколько плохая/хорошая ОС или компилятор.
0
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
17.11.2012, 19:44 #6
std::random_device
Значит, это может работать в винде и без эксепшнов.
Значит, нужно узнать, что за код создает твой компилер. Хотя, бы дизассемблировать и узнать, где эксепшн возникает. Или в рантайме посмотреть, в каком вызове падает.
0
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
17.11.2012, 21:55  [ТС] #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.
0
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
18.11.2012, 01:42 #8
Цитата Сообщение от MrGluck Посмотреть сообщение
точно при попытке создать std::random_device
Ну значит где-то в стандартной библиотеке. "Обратитесь к поставщику" Хотя, хз, на 8-ке проверял, не знаю, как на 7-ке себя поведет.
0
Jupiter
Каратель
Эксперт С++
6568 / 3989 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
18.11.2012, 01:45 #9
MrGluck, не приходило в голову что это просто заглушка с исключением, а сам std::random_device ещё не реализован в этой версии mingw.
юзай бустовый
1
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
18.11.2012, 01:51  [ТС] #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&)"));
    }
    ...
а у вас?
0
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
18.11.2012, 02:14 #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-кого кода, потому что она тут и не нужна, и так вроде видно, что трабла в стандартной либе, поставляющейся с тем компилятором или средой, что ты используешь.
1
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
18.11.2012, 02:24  [ТС] #12
Vourhey, вот в том то и дело, что в MinGW random.h осталась от родного gcc) Как раз, как опубликовал пост с описанием конструктора, так и понял. Думал, мб в качестве параметра конструктора можно будет путь к спец. устройству передать (MS_DEF_PROV на винде). Прийдется ставить буст и менять файл random.h.
0
alex_x_x
бжни
2454 / 1660 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
18.11.2012, 02:34 #13
а зачем ты делаешь (охренительно конечно, что ты не мог вставить код)
C++
1
std::mt19937 gen(rd());
а не
C++
1
std::mt19937 gen(rd);
хотя тут видимо до этого кода дело не доходит
0
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
18.11.2012, 02:44  [ТС] #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'|
0
alex_x_x
бжни
2454 / 1660 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
18.11.2012, 02:53 #15
ok, я посмотрел в описание и удивлен еще больше
что ты делаешь:
ты создаешь std::random_device
std::random_device равномерно распределенных целых генератор случайных чисел, который производит истинно случайных чисел, если недетерминированных источников (например, аппаратное устройство) доступен для реализации.
для того чтобы (sic!) инициализировать другой генератор случайных чисел
rd() - генерирует псевдослучайное число, которое используется для инициализации второго генератора
1
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
18.11.2012, 03:25  [ТС] #16
Цитата Сообщение от alex_x_x Посмотреть сообщение
ok, я посмотрел в описание и удивлен еще больше
что ты делаешь:
ты создаешь std::random_device

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

Добавлено через 4 минуты
Генератор СЧ нужно же как то инициализировать. Почему вас смущает тот факт, что инициализировать будет результат другого ГСЧ, недетерменированного. На srand (time (0)) никто не орет, хотя принцип действия тот же.
0
alex_x_x
бжни
2454 / 1660 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
18.11.2012, 03:30 #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();
}
0
MrGluck
Модератор
Эксперт CЭксперт С++
7980 / 4861 / 1422
Регистрация: 29.11.2010
Сообщений: 13,235
18.11.2012, 03:49  [ТС] #18
alex_x_x, да, есть возможность обойтись без этого, но использование ГСЧ для инициализации добавляет ++ к "случайности". Оно, естественно не делает ГПСЧ ГСЧ (понятно, что истинного ГСЧ не существует, но иначе получилась бы каша в терминах), но начало распределения уже становится неслучайным. Чем инициализировать, все же, по-моему, остается делом вкуса, но думаю не нужно спорить о том, что случайности time(0) может не хватать.

P.S. именно оттуда я и взял способ инициализации, но тогда я не ставил это под сомнение, а принял как данность.
0
soon
2545 / 1310 / 177
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
18.11.2012, 09:07 #19
C++
1
2
3
4
5
6
7
#include <random>
 
int main()
{
    std::mt19937(std::random_device().operator()());
    return 0;
}
Как-то фигово выглядит.
0
Nick Alte
Эксперт С++
1646 / 1018 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
18.11.2012, 09:17 #20
Цитата Сообщение от MrGluck Посмотреть сообщение
понятно, что истинного ГСЧ не существует
Ну как же не существует, когда random_device - это он и есть.
0
18.11.2012, 09:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2012, 09:17
Привет! Вот еще темы с решениями:

Std::bind, std::mem_fun, std::mem_fn
В чем разница между функциями std::bind, std::mem_fun, std::mem_fn?

(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&
astxx::manager::connection::connection(std::basic_string&lt;char,...

Как искать по std::vecotr из std::pait по одному значению из пары?
? :) Пункт 4.7 Правил: Как можно более полно описывайте суть проблемы или...

Реализация класса MyString. Стандартная библиотека, std::string, std::vector
как добавить реализацию конкатенации строк через перегрузку оператора &quot;+=&quot; в...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

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