Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/21: Рейтинг темы: голосов - 21, средняя оценка - 4.62
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175

Какой алгоритм рандомизации для чисел с плавающей запятой выбрать?

14.01.2020, 15:13. Показов 4139. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго!
При попытке генерации двух чисел, методом вихря Мерсенна, происходит неудовлетворительная генерация.
Ставлю диапазон:
C++
1
RandomBetweenDouble(0.0, numeric_limits<double>::max()))
И код:
C++
1
2
3
4
5
6
7
8
double RandomBetweenDouble(double a, double b)
{
    random_device rd;                   //Недетерминированный генератор
    mt19937 gen(rd());                  //Генерация методом вихря Мерсенна
    uniform_real_distribution<> dist(a, b); //Задание границ генерации числа a <= с <= b
    double c = dist(gen);                   //Генерация
    return c;
}
Очень плохо генерирует, про очень плохо, я имею ввиду, что числа, ну в районе Х.ХХе+30Х.
То есть да, случайные числа каждый раз выбрасываются. Но хотелось бы разброс побольше по типу: Х.ХХе+301, Х.ХХе+56, Х.ХХе+81, Х.ХХе+271 итд...
Есть план как это сделать(но он мне очень не нравится): Генерировать вихрем числа от 0.0 до 9.99, переводить это в строку, прикреплять к строке 'e+', генерировать второе число от 0 до 308 int-вым генератором, переводить этот int в строку и присоединять к уже существующей строке, а, затем, уже переводить строку в double.

Но все-таки хочется хороший генератор, потому что он для криптографического алгоритма.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.01.2020, 15:13
Ответы с готовыми решениями:

Программа для умножения чисел с плавающей запятой
Помогите пожалуйста составить программу:cry: Составить программу на ассемблере, для реализации умножения чисел с плавающей запятой ...

Составить программу для вычитания чисел с плавающей запятой
Нужно составить программу, которая переводила бы два вводимых десятичных числа с плавающей запятой в двоичные, вычитала одно число из...

Нормализация чисел с плавающей запятой
Здравствуйте. Пишу макросы для автоматической проверки лабораторных работ. Столкнулась с проблемой: не могу реализовать перевод чисел в...

24
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
14.01.2020, 21:20  [ТС]
Студворк — интернет-сервис помощи студентам
Я пока подумал, числа с плавающей запятой откладываются до лучших времён, будет написана специальная библиотека, которая позволит грамотно обрабатывать R-числа. Пока ограничимся uint64, этого хватит за глаза для гарантии уникальности.
Хочется с помощью функции, передавая два числа, min и max. В нашем случае uint64.
C++
1
2
3
4
5
6
template <typename T>
T RandomBetween(T a, T b)
{
    //Генерация числа с: a<=c<=b
    return c;
}
Равновероятно генерировать любое число из диапазона [а,b].
0
653 / 466 / 183
Регистрация: 23.04.2019
Сообщений: 1,987
14.01.2020, 21:34
Цитата Сообщение от Battary Посмотреть сообщение
Хочется с помощью функции, передавая два числа, min и max.
C++
1
2
3
4
5
6
7
8
9
#include <random>
 
template <typename T>
T RandomBetween(T a, T b)
{
 
    //Генерация числа с: a<=c<=b
    return a + rand() % (b - a + 1);
}
Та на изи

Добавлено через 1 минуту
Цитата Сообщение от Battary Посмотреть сообщение
Равновероятно
нууу) хоть это и псевдорандом, равновероятность не гарантируется
0
694 / 304 / 99
Регистрация: 04.07.2014
Сообщений: 851
15.01.2020, 01:13
Лучший ответ Сообщение было отмечено Battary как решение

Решение

Цитата Сообщение от Battary Посмотреть сообщение
Равновероятно генерировать любое число из диапазона [а,b].
uniform_int_distribution

Цитата Сообщение от AndryS1 Посмотреть сообщение
return a + rand() % (b - a + 1);
ТС просит генератор для криптографии, а не Г на палочке.
Линейный конгруэнтный метод: Возможность использования в криптографии

Хотя линейный конгруэнтный метод порождает статистически хорошую псевдослучайную последовательность чисел, он не является криптографически стойким. Генераторы на основе линейного конгруэнтного метода являются предсказуемыми, поэтому их нельзя использовать в криптографии. Впервые генераторы на основе линейного конгруэнтного метода были взломаны Джимом Ридсом (Jim Reeds), а затем Джоан Бояр (Joan Boyar). Ей удалось также вскрыть квадратические и кубические генераторы. Другие исследователи расширили идеи Бояр, разработав способы вскрытия любого полиномиального генератора. Таким образом, была доказана бесполезность генераторов на основе конгруэнтных методов для криптографии. Однако генераторы на основе линейного конгруэнтного метода сохраняют свою полезность для некриптографических приложений, например, для моделирования. Они эффективны и в большинстве используемых эмпирических тестах демонстрируют хорошие статистические характеристики
Смотри также RANDU

З.Ы. Вихрь Мерсенна тоже не подходит для криптографии, в C++ ближе всего random_device

З.З.Ы. boost/multiprecision/cpp_int.hpp

Добавлено через 55 минут
Для больших чисел почти можно как-то так

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <random>
#include <stdexcept>
 
#include <boost/multiprecision/cpp_int.hpp>
 
using BigInt = boost::multiprecision::cpp_int;
 
BigInt RandomBetween(const BigInt &a, const BigInt &b) {
  std::random_device rd;
 
  uint32_t rd_max = 0xFFFFFFFFu;
  std::uniform_int_distribution<uint32_t> dist(0, rd_max - 1);
 
  BigInt result = 0;
  BigInt c = b - a;
  BigInt d = c * c * c;
 
  while (result < d) {
    result = (result * rd_max) + dist(rd);
  }
 
  result = a + (result % (c + 1));
  return result;
}
 
int main() {
 
  BigInt a{"12345678901234567890123456789012345678901234567890"};
  BigInt b{"99999999999999999999999999999999999999999999999999"};
 
  std::cout << a << std::endl;
  std::cout << b << std::endl;
 
  for (size_t i = 0; i < 20; ++i) {
    std::cout << RandomBetween(a, b) << std::endl;
  }
 
  return 0;
}
Результат
Кликните здесь для просмотра всего текста

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
12345678901234567890123456789012345678901234567890
99999999999999999999999999999999999999999999999999
84434353727817566854949735814101712753062869604816
54852365388108865265514780459831703010383177442774
72722938349669976451898332183523506042007830491414
91701786944064583328625920315131710851831395632563
12891860005374834651976030877153482338361227689416
19391497652302776767276523429483071969929663966749
31246510290710766426537006219961851885631499915112
63142739638384489064140336166034007458469940062915
48019651036249997478795703095539813556873136842845
55097305539494510906019519989780527549675004370758
65872431759959004135933414723046069215759906650028
17461984238493008942936299161587701829099877694877
85103608523904147316296222278348258126263035087968
16234743770117210110865956655546075772230390212124
71979409307681339212122567410913992168907008630702
54548072970661918580115473087487287094664756920051
77575413025963635680239377791432582969291742532156
14170247491759561357916834130360490131442082731127
16140493409717158365950647160684892141084965091810
52122445009448586289329443397338384935987818604741


Если a=0 и b=k^n, где k <= MAX_INT, то можно уйти от остатков
1
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
15.01.2020, 09:18  [ТС]
Сделал 2 варианта:
В этом варианте необходимо будет провести моделирование, чтобы узнать, действительно ли распределение равномерное по всей оси положительных чисел.
C++
1
2
3
4
5
6
7
uint64_t RandomBetweenuint64_t(uint64_t a, uint64_t b)
{
    random_device rd;                       //Недетерминированный генератор
    uniform_int_distribution<uint64_t> dist(a, b);  //Задание границ генерации числа a <= с <= b
    uint64_t c = dist(rd);                          //Генерация
    return c;
}
А этот да, генерирует случайное число на интервале, за счет использования 32бит можно использовать соответствующие генераторы. Его большой минус - чем больше разница между min и max, тем дольше он вычисляет.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
uint64_t RandomBetweenuint64_tByMult(uint64_t a, uint64_t b) 
{
    uint32_t coef = 1;
 
    if ((b - a) > numeric_limits<unsigned long>::max()) 
    { 
        coef = (b - a) / numeric_limits<unsigned long>::max();
    }
 
    random_device rd;
    uniform_int_distribution<uint32_t> dist1(numeric_limits<unsigned long>::min(), numeric_limits<unsigned long>::max());
    uniform_int_distribution<uint32_t> dist2(1, coef);
 
    uint32_t randomBetween = 0;
 
    coef = dist2(rd);
 
    for (size_t i = 0; i < coef; i++)
    {
        randomBetween += dist1(rd);
    }
 
    uint64_t c = a + randomBetween;
    return c;
}
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
15.01.2020, 09:29
Цитата Сообщение от Croessmah Посмотреть сообщение
Зачем real для генерации целого?
Низачем, обычный копипаст
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.01.2020, 09:29
Помогаю со студенческими работами здесь

Округление чисел с плавающей запятой
Здравствуйте товарищи программисты. Есть вопрос по функции FloatToStrF. Для моей задачи нужно записывать в текстовый файл числа с точностью...

Сравнение чисел с плавающей запятой
Сравнение чисел с плавающей запятой. В этой теме я попробую &quot;просто&quot; объяснить новичкам в программировании что есть тип double...

Вычисления с чисел с плавающей запятой
Есть в БД поле с числом (например 0,12). Формат в БД: Одинарное с плавающей точкой, Основной, 2 цифры после запятой. Нужно умножить...

Произведение чисел с плавающей запятой
Требуется реализовать произведение чисел с плавающей запятой, длинных чисел, к примеру 1234567890.9 и 1234567890.9, так что бы их результат...

Умножение чисел с плавающей запятой
Тут произошёл интересный случай, когда сделал умножение я увидел что любое число например это будет 3 ,может множется на любое кроме тех, у...


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

Или воспользуйтесь поиском по форуму:
25
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru