Найдите минуту / макс. из плавающего/двойного, которое имеет то же внутреннее представление

Один пример из многих: шаблонное метапрограммирование. Никто в комитете по стандартам не намеревался там быть полным по Тьюрингу подъязыком, который выполняется во время компиляции.

Шаблонное метапрограммирование является едва скрытой функцией. Это находится даже в библиотеке повышения. См. MPL. Но если "почти скрытый" достаточно хорошо, то смотрите на библиотеки повышения . Это содержит много конфет, которые не являются легки доступный без поддержки сильной библиотеки.

Один пример библиотека boost.lambda , которая интересна, так как C++ не имеет функций лямбды в текущем стандарте.

Другой пример Loki, который "делает широкое применение шаблонного метапрограммирования C++ и реализует несколько наиболее часто используемых инструментов: список типов, функтор, одиночный элемент, интеллектуальный указатель, возражает фабрике, посетителю и мультиметодам". [ Википедия ]

7
задан Community 23 May 2017 в 12:25
поделиться

2 ответа

Один из способов ответить на ваш вопрос - найти размер ULP или U нит в L ast P lace, вашего числа с плавающей запятой. Немного упрощая, это расстояние между заданным числом с плавающей запятой и следующим большим числом. Опять же, немного упрощая, учитывая представимое значение x с плавающей запятой, любая десятичная строка, значение которой находится между (x - 1/2 ulp) и (x + 1/2 ulp), будет округлено до x при преобразовании в плавающее -point.

Хитрость заключается в том, что (x +/- 1/2 ulp) не является представимым числом с плавающей запятой, поэтому для фактического вычисления его значения требуется, чтобы вы использовали более широкий тип с плавающей запятой (если он доступен ) или большой десятичной дроби произвольной ширины или аналогичный тип для выполнения вычислений.

Как определить размер язвы? Один относительно простой способ примерно соответствует тому, что вы предложили, здесь написан псевдокод C-ish, потому что я не знаю C #:

float absX = absoluteValue(x);
uint32_t bitPattern = getRepresentationOfFloat(absx);
bitPattern++;
float nextFloatNumber = getFloatFromRepresentation(bitPattern);
float ulpOfX = (nextFloatNumber - absX);

Это работает, потому что добавление единицы к битовому шаблону x в точности соответствует добавлению одного ulp к значению x . При вычитании не происходит округления с плавающей запятой, потому что задействованные значения настолько близки (в частности, есть теорема арифметики с плавающей запятой ieee-754, что если два числа x и y удовлетворяют условию y / 2 <= x <= 2y, тогда x - y вычисляется точно). Единственное предостережение:

  1. если x окажется наибольшим конечным числом с плавающей запятой, это не сработает (вернет inf , что явно неверно).
  2. если ваша платформа некорректно поддерживает постепенное опустошение (например, встроенное устройство, работающее в режиме сброса до нуля), это не сработает для очень малых значений x.

Похоже, вы вряд ли попадете ни в одну из этих ситуаций, поэтому для ваших целей это должно работать.

Теперь, когда вы знаете, что такое ulp of x есть, вы можете найти интервал значений, который округляется до x. Вы можете вычислить ulp (x) / 2 точно с плавающей запятой, потому что деление с плавающей запятой на 2 является точным (опять же, без потери значимости). Затем вам нужно только вычислить значение x +/- ulp (x) / 2 подходящего большего типа с плавающей запятой ( double будет работать, если вас интересует float ) или тип Big Decimal, и у вас есть свой интервал.

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

неверен. Вы просто случайно смотрели неверные значения (0,999999 ... вместо 0,099999 ... - простая опечатка).

6
ответ дан 7 December 2019 в 07:46
поделиться

Python 3.1 только что реализовал что-то вроде этого: см. журнал изменений (прокрутите немного вниз) , отчет об ошибке .

1
ответ дан 7 December 2019 в 07:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: