Uniform_real не принимает numeric_limits :: low ()

У меня есть строчка:

std::uniform_real_distribution<T> distribution(std::numeric_limits<T>::lowest(), 
                                               std::numeric_limits<T>::max());

Он компилируется, но вылетает при отладке (VS 2017CE). Я предполагаю, что согласно документации std::uniform_real_distribution:

Requires that a ≤ b and b-a ≤ std::numeric_limits<RealType>::max()

когда мой b - это ::max(), а a - это ::lowest(), условие:

b-a ≤ std::numeric_limits<RealType>::max()

не выполняется, поскольку b-a в основном удваивает значение max. Есть ли какой-нибудь способ обойти это, чтобы я сохранил такой широкий диапазон чисел? ::min() работает отлично, но пропускает отрицательные значения. Проблема возникает только для чисел с плавающей запятой.

Итак, вы хотите равномерного распределения по всему диапазону T?

hellow 27.08.2018 14:14

@hellow Именно так. Может быть немного меньше, но максимально широким.

PStarczewski 27.08.2018 14:16

Возможно, есть более разумное решение, но если все не удается, вы можете использовать два диапазона (отрицательная и положительная полуось) и случайным образом выбрать один для опроса. Или, что эквивалентно IEEE754, используйте [0, max] и случайным образом меняйте знак.

Baum mit Augen 27.08.2018 14:25

У меня есть ответ, но я хотел бы спросить, какое поведение вы ищете в первую очередь. Диапазон [lowest, max) будет давать большую часть своих результатов ближе к двум концам, поскольку на концах гораздо больше чисел, чем в середине. Вы хотите такого поведения или хотите, чтобы меньшие числа имели одинаковые шансы появиться?

NathanOliver 27.08.2018 14:54

@NathanOliver Большинство результатов, имеющих большую величину, можно было бы ожидать при использовании равномерного распределения, не так ли?

Baum mit Augen 27.08.2018 14:56

@NathanOliver Мне нужны значения по краям диапазона. Мне не нужно какое-то конкретное число, только максимальная ширина диапазона.

PStarczewski 27.08.2018 14:57

@BaummitAugen Некоторые люди не ожидают такого поведения

NathanOliver 27.08.2018 14:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
7
256
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Одно простое решение, по крайней мере для обычных чисел с плавающей запятой IEEE-754, - это случайное изменение знака случайного неотрицательного числа:

std::uniform_real_distribution<T> distribution(0., 
                                               std::numeric_limits<T>::max());
auto rn = distribution(eng);
return someRandomFlag ? rn : -rn;

где someRandomFlag выбирается единообразно из {true, false}.

Думаю, я пойду на это, потому что это просто и чисто. Спасибо. Однако я подожду и приму это как решение, потому что мне просто любопытно, почему это вообще происходит, и, возможно, кто-то узнает.

PStarczewski 27.08.2018 15:04

@PStarczewski Вы уже знаете, почему это происходит. uniform_real_distribution требует, чтобы b-a <= max.

Sneftel 27.08.2018 15:27

Обратите внимание, что это может привести к смехотворно небольшому перевесу 0, поскольку 0 и -0 равны.

Yakk - Adam Nevraumont 27.08.2018 16:08

@ Yakk-AdamNevraumont пока 0. == -0., Они не совпадают.

Dan M. 26.09.2018 14:07

@DanM. • одно и то же число (математически говоря), разные представления. -0. встречается в некоторых крайних случаях. Лечился так же ... в основном. Иногда бывает сложно различить их, когда такое различение желательно.

Eljay 26.09.2018 14:24

«Математика» здесь не актуальна, поскольку числа с плавающей запятой / добулы не являются вещественными числами. Для компьютеров все иначе. Это, вероятно, не имеет значения для большинства целей, но это стоит знать. Например, хотя uniform_real_distribution является «однородным», у некоторых чисел будет гораздо больше шансов быть выбранными, чем у других, только потому, что распределение с плавающей запятой не является равномерным.

Dan M. 26.09.2018 14:55

@DanM. Каждое число с плавающей запятой можно рассматривать как представление диапазона действительных чисел; Теоретически равномерное реальное распределение может дать каждому числу с плавающей запятой шанс, соизмеримый с мерой представленного набора действительных чисел. «Математика» здесь очень уместна; при игнорировании получаешь ерунду.

Yakk - Adam Nevraumont 26.09.2018 15:46

@Yakk - Adam Nevraumont да, но вы получите неоднородные числа, которые будут одинаковыми только в отношении представленных интервалов. Это важное различие. Это обсуждение возникло из-за «смехотворно небольшого завышения 0». Если мы начнем говорить о «весах», больше не имеет смысла говорить о реальных числах. компьютерные двойники уже сильно неоднородны (с точки зрения «вероятности генерировать это число») с любым таким распределением.

Dan M. 26.09.2018 17:56

@DanM. Вероятность на бесчисленных множествах выражается как меры подмножеств; разделение вещественных чисел на классы эквивалентности и использование чисел с плавающей запятой в качестве имени класса эквивалентности имеет смысл и является разумным способом говорить о реальном равномерном распределении значений с плавающей запятой (или действительно о любом реальном равномерном распределении; все действительные числа имеют вероятность 0 выбирается в равномерном распределении). Все это имеет смысл и прямо следует из «Математики». Ваши возражения, кажется, указывают на заблуждение относительно теории меры и теории вероятностей, что является обычным явлением.

Yakk - Adam Nevraumont 26.09.2018 18:57

@Yakk - Адам Неврамонт, нет бесчисленных наборов на ПК. И не имеет значения, «проверяет» ли лежащая в основе математика (я не сомневаюсь в этом), но программист не имеет дела с идеальными математическими системами. Для программиста может быть очень удивительно узнать, что какое-то значение X генерируется в 1000 раз больше, чем какое-то другое значение Y в предположительно однородном распределении (его не волнует, принадлежит ли оно к классу, представляющему интервал в 1000 раз больше или нет)

Dan M. 26.09.2018 20:42

@DanM. Да, программисты, которые не понимают, что означает «равномерное реальное распределение», не поймут, что он делает. Возможно и ожидаемо, что «равномерное реальное распределение» означает «равномерное реальное распределение». Действительные числа, которые представляет данное значение с плавающей запятой (т. Е. Округляются до этой плавающей запятой), четко определены в стандарте IEEE. Тем не менее, это непродуктивно. До свидания.

Yakk - Adam Nevraumont 26.09.2018 20:47
Ответ принят как подходящий

Один из способов сделать это - использовать диапазон [-1, 1], а затем умножить его на std::numeric_limits<T>::max(), чтобы получить фактическое число. Это позволяет удовлетворить требования b-a ≤ std::numeric_limits<RealType>::max().

auto dis = std::uniform_real_distribution<T> dis(-1, std::nextafter(1, std::numeric_limits<T>::max()));
return dis(eng) * std::numeric_limits<T>::max();

Это не даст вам всех возможных значений с плавающей запятой, но даст вам хорошее количество из них, распределенных, как uniform_int_distribution.

Вы уверены, что этим можно достичь всех возможных значений?

Baum mit Augen 27.08.2018 15:06

@BaummitAugen Я почти уверен, что это не так, но он ведет себя как uniform_int_distribution для диапазона значений. Зависит от того, как ОП на самом деле хочет, чтобы результаты распределялись.

NathanOliver 27.08.2018 15:08

Это кажется противоречивым. Для равномерного распределения, скажем, в диапазоне double, каждое число должно иметь положительную вероятность (которая, конечно, зависит от его величины).

Baum mit Augen 27.08.2018 15:10

@BaummitAugen Я никогда не видел реализации uniform_real_distribution, которая действительно достигла бы этого свойства. Нормальный подход - это просто u01 * (max-min) + min.

Sneftel 27.08.2018 15:15

@Sneftel Возможно, никогда не проверял подробно. Но так и должно быть, по крайней мере, в теории.

Baum mit Augen 27.08.2018 15:21

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

PStarczewski 27.08.2018 15:22

@PStarczewski Знаешь, почему что происходит?

NathanOliver 27.08.2018 15:22

@PStarczewski это (сбой) происходит из-за того, что вы нарушаете задокументированные требования дистрибутива?

Yakk - Adam Nevraumont 27.08.2018 15:34

@ Yakk-AdamNevraumont Я не уверен. Я только что протестировал его на linux и отлично работает в отличие от windows. Не могу понять, почему.

PStarczewski 27.08.2018 15:36

@PStarczewski Нарушение контракта является неопределенным поведением. В контракте указано, что это b-a ≤ std::numeric_limits<RealType>::max(), и если вы его нарушите, все ставки отключены. Он мог работать, он мог не компилироваться, он мог дать сбой, он мог дать вам неправильные результаты, он мог выпустить моих собак со двора, и мне пришлось потратить полчаса, преследуя их. Неопределенное поведение означает, что он может делать то, что хочет.

NathanOliver 27.08.2018 15:38

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

PStarczewski 27.08.2018 15:38

@NathanOliver Спасибо за объяснение!

PStarczewski 27.08.2018 15:39

Другие вопросы по теме