Для корректной работы умных указателей вам необходимо определить DReference& DReference::operator = (const DReference&), либо удалить его реализацию по-умолчанию — не знаю, сделали вы это или нет. Реализация по-умолчанию в вашем случае приводит к ошибкам.
Аха, забавно: при установке он умоляет принять участие в «улучшении сервисов Яндекса» — отправлять автоматические отчёты, а ту же самую настройку в IE считает за уязвимость.
Преимущества в точности. Хорошо, объясню подробно. Числа с плавающей точкой устроены так, что чем ближе число к нулю тем выше точность (тем ближе расположены соседние числа). Для double погрешность хранения числа, близкого к 1, составляет 2-53 (см. en.wikipedia.org/wiki/Machine_epsilon), для чисел, близких к нулю, она будет на порядки меньше. А в данном случае — погрешность очень важный параметр, поскольку в конечном итоге множитель возводится в очень большую степень порядка 100 000. Собственно, резон алгоритма, описанного по ссылке www.musicdsp.org/showone.php?id=189 в этом и состоит: для величины m, близкой к 1 вычисляется и используется параметр m-1. Я думаю, что больше нет ни одной причины не использовать формулу
По поводу 0.001 меня смущает в первую очередь то, что на слух это ужасно. Если, например, период release установлен в 0.2 сек, то экспоненциальное спадание от 1 до 0.001 будет означать затухание в 31 раз (~= корень из 1000) за первые 0.1 сек. Я поэксперементировал с этим параметром и нашёл, что гораздо более комфортно воспринимается значение 0.05 вместо 0.001.
Теперь по поводу алгоритма. Резон неточных вычислений, описанных в статье www.musicdsp.org/showone.php?id=189 понятно какой, и это не эффективность вычислений, которая у вычисления двух логарифмов будет никак не меньше, чем у вычисления одной экспоненты, а именно точность: вместо числа 1+ε хранится и вычисляется ε. Но в статье, которую вы переводили к этому эпсилон прибавляется 1, и все преимущества сразу теряются. На самом деле, их и не было, поскольку в вышеупомянутом пределе скорость сходимости не такая, чтобы для разумных количеств отсчётов математическая погрешность, возникающая в алгоритме статьи оказывалась бы меньше погрешности double, которая возникает тупом при вычислении в лоб. Поэтому вывод: по ссылке www.musicdsp.org/showone.php?id=189 описан алгоритм обоснованный, но на практике неправильный. В статье этот алгоритм неправильно используется, так что получается необоснованно и неправильно.
Интересно, зачем для множителя выбирается число (1+ln(x)/n), которое в степени n лишь приближённо равно нужному значению x по формуле et = lim (1+t/n)n?
Это имеет смысл, если мы будем писать как в статье, на которую ссылка:
А именно, этот смысл заключается в том, что вместо числа 1+ε хранится и вычисляется ε, что при маленьком ε может обеспечить гораздо большую точность.
На практике же для разумных n гораздо более точным оказывается вычисление множителя «в лоб»: multiplier = pow(endLevel / startLevel, 1. / lengthInSamples );
А вот что действительно непонятно, так это взятое «с потолка» значение 0.001 для нуля. Дело в том, что при экспоненциальном характере огибающей порядок этого значения прямо влияет на скорость затухания/атаки. Иными словами, если вместо 0.001 использовать 0.0001, то скорость затухания будет значительно более большой.
Я не знаю, на каком языке у вас алгоритм (у вас ни в одном месте этого не сказано), так что считаю, что это псевдокод. В случае $dicesCount <= 1 у вас возможно обращение по отрицательному индексу массива, предполагаю, что это скорее падение.
Смысл писать просто «случайным образом»? Задача будет иметь смысл если задать распределение. Например, равномерное. А в вашем алгоритме оно не равномерное отнюдь.
Пример: число 4, кубиков: 3.
вероятность варианта 2 1 1 равна сумме вероятностей вариантов 1 2 1 и 1 1 2
Кроме того, ваш алгоритм падает при кол-ве кубиков <= 1.
Один из смыслов состоит в том, чтобы не навязывать разработчику Стандартную библиотеку. В Плюсах никто не заставляет инклюдить хедер, содержащий std::exception, да и вообще, в части Стандарта, которая не касается Стандартной библиотеки, никакие «особенные» типы не упомянаются. Так во всяком случае было до C11, в котором языковая контрукция initializer list судя по всему требует обязательного включения соотв хедера.
В Плюсах можно просто придерживаться правила: никогда не бросать ничего, кроме std::exception. Этому правилу придерживается Стандартная библиотека, и если ему следовать, то всё будет норм.
Сегодня Mail.ru внезапно стал поисковиком по-умолчанию в Crome на Android. Единственное, что я делал — просматривал через web-интерфейс Gmail письмо, отправленное с Mail.ru. У меня шок, если честно.
Уведомляем вас, что на территории России официальными наименованиями России являются «Россия» и «Российская Федерация». Наименование «Роисся» на основании вышеперечисленного является суррогатом и может использоваться для финансирования терроризма, борцов с коррупцией, бандеровцев или иной противоправной деятельности. Использование других суррогатов названия является грубым нарушением закона. Просьба явиться, расписаться,
Кстати говоря, в обычной аксиоматике ZF вопреки часто встречающимуся заблуждению объединение счётного кол-ва счётных множеств счётным быть не обязано. Это соотношение зависит от ксиомы выбора.
EDIT: ошибся с веткой немного
multiplier = pow(endLevel / startLevel, 1. / lengthInSamples );
Теперь по поводу алгоритма. Резон неточных вычислений, описанных в статье www.musicdsp.org/showone.php?id=189 понятно какой, и это не эффективность вычислений, которая у вычисления двух логарифмов будет никак не меньше, чем у вычисления одной экспоненты, а именно точность: вместо числа 1+ε хранится и вычисляется ε. Но в статье, которую вы переводили к этому эпсилон прибавляется 1, и все преимущества сразу теряются. На самом деле, их и не было, поскольку в вышеупомянутом пределе скорость сходимости не такая, чтобы для разумных количеств отсчётов математическая погрешность, возникающая в алгоритме статьи оказывалась бы меньше погрешности double, которая возникает тупом при вычислении в лоб. Поэтому вывод: по ссылке www.musicdsp.org/showone.php?id=189 описан алгоритм обоснованный, но на практике неправильный. В статье этот алгоритм неправильно используется, так что получается необоснованно и неправильно.
Это имеет смысл, если мы будем писать как в статье, на которую ссылка:
(я убрал 1 из multiplier).
А именно, этот смысл заключается в том, что вместо числа 1+ε хранится и вычисляется ε, что при маленьком ε может обеспечить гораздо большую точность.
На практике же для разумных n гораздо более точным оказывается вычисление множителя «в лоб»:
multiplier = pow(endLevel / startLevel, 1. / lengthInSamples );
А вот что действительно непонятно, так это взятое «с потолка» значение 0.001 для нуля. Дело в том, что при экспоненциальном характере огибающей порядок этого значения прямо влияет на скорость затухания/атаки. Иными словами, если вместо 0.001 использовать 0.0001, то скорость затухания будет значительно более большой.
Пример: число 4, кубиков: 3.
вероятность варианта 2 1 1 равна сумме вероятностей вариантов 1 2 1 и 1 1 2
Кроме того, ваш алгоритм падает при кол-ве кубиков <= 1.
В Плюсах можно просто придерживаться правила: никогда не бросать ничего, кроме std::exception. Этому правилу придерживается Стандартная библиотека, и если ему следовать, то всё будет норм.