Russian Qt Forum
Ноябрь 26, 2024, 16:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: вопросы по функции qrand();  (Прочитано 6898 раз)
Alexu007
Гость
« : Март 10, 2014, 21:24 »

1. выдаёт (по умолчанию) случайные числа в диапазоне 0 - 32767, что как-то маловато, хотелось бы как минимум половину int.

2. При вызове диалога выбора файла QFileDialog::getOpenFileName происходит "несанкционированная" инициализация ГСЧ случайным числом. Никак не мог понять где косяк, почему без инициализации не получается одна и та же последовательность - для отладки.
« Последнее редактирование: Март 10, 2014, 21:27 от Alexu007 » Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Март 10, 2014, 22:18 »

Цитировать
1. выдаёт (по умолчанию) случайные числа в диапазоне 0 - 32767, что как-то маловато, хотелось бы как минимум половину int.
http://doc.qt.digia.com/4.6/qtglobal.html#qrand
Цитировать
Returns a value between 0 and RAND_MAX (defined in <cstdlib> and <stdlib.h>), the next number in the current sequence of pseudo-random integers.
Цитировать
/*
 * RAND_MAX is the maximum value that may be returned by rand.
 * The minimum is zero.
 */
#define   RAND_MAX   0x7FFF
Ничего с этим не поделаешь Улыбающийся

По второму пункту не понятно. Надо бы кода Улыбающийся
Записан

m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #2 : Март 11, 2014, 09:22 »

А кроме qrand() ничего уже нет?

Код
C++ (Qt)
   const int rand_max = 100000000;
   std::mt19937 gen;
   std::uniform_int_distribution<int> dist(0, rand_max);
 
   std::cout << dist(gen) << std::endl;
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Март 11, 2014, 14:00 »

Цитировать
/*
 * RAND_MAX is the maximum value that may be returned by rand.
 * The minimum is zero.
 */
#define   RAND_MAX   0x7FFF
Не на всех платформах, напр Xcode (stdlib.h)
Код
C++ (Qt)
#define RAND_MAX 0x7FFFFFFF
 
1. выдаёт (по умолчанию) случайные числа в диапазоне 0 - 32767, что как-то маловато, хотелось бы как минимум половину int.
Так склейте
Код
C++ (Qt)
inline quint32 RandInt( void )
{
return (qrand() << 16) | qrand();
}
 

А кроме qrand() ничего уже нет?

Код
C++ (Qt)
   const int rand_max = 100000000;
   std::mt19937 gen;
   std::uniform_int_distribution<int> dist(0, rand_max);
 
   std::cout << dist(gen) << std::endl;
 
А можно обойтись и куда более скромными средствами, напр
Код
C++ (Qt)
void RandSeed( quint32 & seed )
{
 seed = (qint32)(seed) * 1103515245 + 12345;
}
 
« Последнее редактирование: Март 11, 2014, 14:02 от Igors » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #4 : Март 11, 2014, 14:28 »

Цитировать
Так склейте
Код
C++ (Qt)
inline quint32 RandInt( void )
{
return (qrand() << 16) | qrand();
}
 
Это плохое, неэффективное решение.. Во-первых лишний вызов qrand, во-вторых, хз как это отразиться на качестве псевдослучайной последовательности. В-третьих, если потребуется изменить диапазон, то вновь потребует лишние телодвижения..
Никаких преимуществ у этого решения перед тем, что предлагает stl нет, лишь напротив..      


Цитировать
А можно обойтись и куда более скромными средствами, напр
Код
C++ (Qt)
void RandSeed( quint32 & seed )
{
 seed = (qint32)(seed) * 1103515245 + 12345;
}
 
Это уже костыль, и не понятно какое отношение это имеет к генераторам и распределениям в std::

« Последнее редактирование: Март 11, 2014, 14:32 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Март 11, 2014, 16:11 »

Никаких преимуществ у этого решения перед тем, что предлагает stl нет, лишь напротив..      
Преимущество громадное - обойтись без всего того страхомудия которым Вы забиваете себе голову Улыбающийся Диапазон решается напр так
Код
C++ (Qt)
double RandSeedF( quint32 & seed )
{
RandSeed(seed); // как выше
return seed * 2.328306436E-10f;
}
 

хз как это отразиться на качестве псевдослучайной последовательности.
Усиленное запоминание std не компенсирует пробелов в фундаментальных знаниях.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #6 : Март 11, 2014, 16:27 »

Преимущество громадное - обойтись без всего того страхомудия которым Вы забиваете себе голову Улыбающийся
Откровенная чушь. Видимо, как следствие комплексов и фобий перед механизмами и решениями stl, boost и т.д..  
Т.е. вы действительно не понимаете, почему вариант stl более гибок и эффективен, чем предложенное вами страхомудия?


Цитировать
Усиленное запоминание std не компенсирует пробелов в фундаментальных знаниях.
Пафоса то, пафоса  Смеющийся

 


  
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Март 11, 2014, 16:28 »

Усиленное запоминание std не компенсирует пробелов в фундаментальных знаниях.
Вы наконец открыли для себя Кнута? Похвально.
А объяснить сможете что происходит в этом коде? Ну с вашими фундаментальными знаниями это должно быть не сложно. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Март 11, 2014, 19:11 »

Откровенная чушь. Видимо, как следствие комплексов и фобий перед механизмами и решениями stl, boost и т.д..  
Т.е. вы действительно не понимаете, почему вариант stl более гибок и эффективен, чем предложенное вами страхомудия?
Неужели Вы настолько наивны и полагаете что я придумал эти числа? Улыбающийся Конечно нет, этим простеньким генератором я пользуюсь с начала 90-х. Так зачем мне цеплять "нечто" и потом с ним возиться? Не говоря уже о том что проект может быть и не совместим с С++ 11. Если просто - то значит плохо? Чем? Может тем что я вынужден таскать с собой переменную seed - ну так ведь и Ваш вариант не thread-safe (поправьте если не так). Ой, щас пойдет в ход что-то типа "thread_local"  Улыбающийся

Откуда такая уверенность что "вариант stl более гибок и эффективен"? На деле это может оказаться совсем не так. Давно хотел пощупать вариации "cellular" где довольно интенсивный рандом, интересно - расскажу.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Март 11, 2014, 19:19 »

Неужели Вы настолько наивны и полагаете что я придумал эти числа?
Нет, не думаем. И Кнута вы к сожалению не открыли. Так, нашли один из вариантов в интернете...
Да, серьезные фундаментальные знания, впрочем как всегда. Улыбающийся

Так зачем мне цеплять "нечто" и потом с ним возиться?
А вот если бы вы открыли Кнута, то узнали для себя, что генераторы сильно отличаются по качеству. Улыбающийся
« Последнее редактирование: Март 11, 2014, 19:25 от Old » Записан
Alexu007
Гость
« Ответ #10 : Март 11, 2014, 20:19 »

По второму пункту не понятно. Надо бы кода Улыбающийся

Код
C++ (Qt)
#include "widget.h"
#include "ui_widget.h"
 
#include <QMessageBox>
#include <QFileDialog>
 
 
Widget::Widget(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::Widget)
{
   ui->setupUi(this);
 
   QObject::connect(ui->pushButton_1, SIGNAL(clicked()), this, SLOT(MyEventButton_1()));
 
 
 
}
 
Widget::~Widget()
{
   delete ui;
}
 
 
 
// нажатие кнопки
void Widget::MyEventButton_1()
{
 
   int x;
   QString str;
   QMessageBox msgBox;
 
/*
   str = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                   "C:/temp/", tr("*"));
*/

 
   for(int i = 0; i < 10; i++)
   {
       x = qrand();
       msgBox.setText(QString::number(x));
       msgBox.exec();
   }
 
return;
}

Вот так при нажатии кнопки выдаёт одну и ту же последовательность псевдостучайных чисел. Что правильно, т.к. нет иниалицизации ГСЧ случайным числом. Но если вызвать меню выбора файла - в коде оно закомментировано - то при нажатии кнопки ессно выскочит это меню  (можна выбрать любой файл или вообще ничего не выбирать - пофиг). И после меню каждый раз будет разная последовательность псевдослучайных чисел.

На мой взгляд небольшой глючок - где-то в коде меню инициализируется ГСЧ. Я просто никак не мог понять, чего это ГСЧ у меня баловать начал...

Проблему больших чисел решил просто: перемножил два соседних случайных числа. Качество последовательности меня не очень интересует, но нужно чтобы диапазон был больше.
« Последнее редактирование: Март 11, 2014, 20:26 от Alexu007 » Записан
Bepec
Гость
« Ответ #11 : Март 11, 2014, 23:33 »

Вопрос а зачем вам неслучайная случайная последовательность чисел?

PS вариант "для отладки" не катит. Для отладки сделайте там ifdef и выдавайте числа от 0 до N.
Записан
Alexu007
Гость
« Ответ #12 : Март 11, 2014, 23:48 »

Как раз таки для отладки. Но в общем это легко обходится - после вызова меню файла нужно переинициализировать ГСЧ любым неслучайным  числом. Тогда последовательность цифр снова станет повторяющейся.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Март 12, 2014, 06:58 »

На мой взгляд небольшой глючок - где-то в коде меню инициализируется ГСЧ. Я просто никак не мог понять, чего это ГСЧ у меня баловать начал...
Или просто "используется". Thread-safe реализация гарантирует что последовательность та же самая независимо от вызовов в до нитках. Но что вызов ф-ции Qt не изменит расклад в текущей - этого никто не обещал.

Проблему больших чисел решил просто: перемножил два соседних случайных числа. Качество последовательности меня не очень интересует, но нужно чтобы диапазон был больше.
Хоть диапазон и больше, но так маленькие числа будут выпадать часто, а большие - редко. Распределение перестало быть равномерным
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.621 секунд. Запросов: 23.