Если аргумент равен нулю, то возвращает наименьшее репрезентабельное значение: например, для типадвойнойэто будет либоstd::числовые_лимиты<двойной>::мин::числовые_лимиты>двойнойв зависимости от того, поддерживаются ли денормы(которые имеют значения 2.2250738585072014e-308и4.940656454654e-324соответственно.
Если результат слишком мал для представления, то возвращается наименьшее репрезентабельное значение.
Всегда возвращает положительное значение так, чтоulpx]==ulp[-x.
Важно:Поведение этой функции соответствует поведению ulp-функцииJava, однако обратите внимание, что эта функция должна использоваться только для грубых и готовых вычислений, поскольку существует достаточно угловых случаев, чтобы заманить в ловушку даже осторожных программистов. В частности:
Функция асимметрична, то есть данаu=ulpx, еслиx>0, тоx+uявляется следующим значением с плавающей точкой, ноx-уне обязательно является предыдущим значением. Аналогично, еслиx<0, тоx-уявляется прежним значением с плавающей точкой, ноx+уне обязательно является следующим значением. Угловые случаи происходят при мощности 2 границ.
Когда аргумент становится очень маленьким, может оказаться, что нет значения с плавающей точкой, которое представляет одно ULP. Является ли это так или нет, зависит не только от того, может ли оборудование.иногдаподдерживают денормы (по сигналуstd::числовые_лимиты<FPT>::имеют_денорму), но также и то, включены ли они в настоящее время во время выполнения (например, на аппаратном обеспечении SSE, флаги DAZ или FTZ отключат денормальную поддержку). В этой ситуации функцияulpможет возвращать значение, которое слишком велико на много порядков.
В свете вышеизложенных вопросов мы рекомендуем следующее:
Чтобы перемещаться между соседними значениями плавающей точки, всегда используйтеfloat_next,float_priorилиследующаяstd::следующаяявляется еще одним кандидатом, но наш опыт показывает, что это также часто нарушается в зависимости от того, какие оптимизации и аппаратные флаги действуют.
Для перемещения нескольких значений с плавающей запятой используйтеfloat_advance.
Существует не менее важный пример использования этой функции:
Если известно, что истинным результатом некоторой функции является xtи вычисленным результатом является xc, то ошибка, измеренная в ulp, является простоfabs(xt- xc) / ulp(xt).
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.