`nextafter` и` nexttoward`: почему именно этот интерфейс? - PullRequest
0 голосов
/ 28 августа 2018

Что именно является причиной этого специфического интерфейса nextafternexttoward) функций ? Мы указываем направление , указав значение, которое мы хотим переместить в направлении .

На первый взгляд кажется, что за этой идеей скрыто что-то неочевидное. По моему (наивному) мнению, первым выбором для таких функций будет что-то вроде пары однопараметрических функций nextafter(a) / nextbefore(a). Следующим выбором будет двухпараметрическая функция nextafter(a, dir), в которой направление dir указано явно (-1 и +1, некоторое стандартное перечисление и т. Д.).

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

  1. (расплывчато). Может быть какая-то умная идея или идиоматический паттерн, настолько ценный, что он повлиял на выбор интерфейса в этих стандартных функциях. Есть ли?

  2. Что если вы решите просто слепо использовать -DBL_MAX и +DBL_MAX в качестве второго аргумента для nextafter, чтобы указать отрицательное и положительное направление соответственно. Есть ли какие-либо подводные камни в этом?

  3. (уточнение 2). Если я точно знаю, что b [немного] больше, чем a, есть ли основания предпочесть nextafter(a, b) над nextafter(a, DBL_MAX)? Например. есть ли шанс улучшить производительность для nextafter(a, b) версии?

  4. Является ли nextafter обычно тяжелым операцией? Я знаю, что это зависит от реализации. Но, опять же, предполагая реализацию, основанную на представлениях IEEE 754, довольно ли «сложно» найти соседнее значение с плавающей точкой?

1 Ответ

0 голосов
/ 28 августа 2018

В двоичных представлениях с плавающей запятой IEEE-754, если оба аргумента nextafter конечны, а два аргумента не равны, результат можно вычислить, либо сложив один из них, либо вычтя один из представления переосмысленного числа как целое число без знака [Примечание 1]. (Небольшая) сложность является результатом правильного обращения с угловыми случаями, которые не отвечают этим предварительным условиям, но в целом вы обнаружите, что это очень быстро.

Помимо NaN, единственное, что имеет значение для второго аргумента, это то, больше ли он, меньше или равен первому аргументу.

Интерфейс в основном обеспечивает дополнительную ясность для результатов углового случая, но это также иногда полезно. В частности, использование nextafter(x, 0), которое усекается независимо от знака, часто удобно. Вы также можете воспользоваться тем фактом, что nextafter(x, x); равен x, чтобы ограничить результат произвольным значением.

Разница между nextafter и nexttowards заключается в том, что последний позволяет использовать больший динамический диапазон long double; опять же, это помогает в определенных угловых случаях.


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