689
правок
Изменения
м
Переключение режима округления в процессоре является довольно длительной операцией, поэтому, если использовать его в каждой элементарной операции, это может сильно замедлить вычисления. Впрочем, эту проблему можно легко решить. {{TODO| t=написать о решении}}
первая адекватная версия
== Применение в вычислительной геометрии ==
Допустим, нам нужно точно определить знак некоторого выражения (это может потребоваться, например, при вычислении предиката [[Предикат "левый поворот" |"левый поворот"]]). ЯсноБудем использовать для его вычисления интервальную арифметику. Все исходные переменные, входящие в него, будут вырожденными интервалами. При выполнении одной из элементарных операций, что минимальное значение будетописанных выше, если все округлять будем вычислять нижнюю границу с округлением вниз, а максимальное верхнюю - если с округлением вверх. {{TODO| t=поподробнее об этом}}Из-за погрешностей, возникающих при округлении вещественных чисел, истинные значения операций нам неизвестны, но они обязательно будет содержаться в посчитанных интервалах. Если левая и правая границы интервала для всего выражения оказались одного знака, то и само выражение однозначно будет иметь тот же знак. В противном случае требуются дополнительные действия. Режим округления и другие настройки вещественной арифметики в C++ можно изменить с помощью функции _controlfp (MSDN рекомендует использовать более безопасную версию _controlfp_s).
== Проблемы и ограничения ==
Переключение режима округления в процессоре является довольно длительной операцией, поэтому, если использовать его в каждой элементарной операции, это может сильно замедлить вычисления. Впрочем, эту проблему можно легко решить. Пусть мы вычисляем операцию <tex>l = a \circ b </tex> с округлением вниз, тогда <tex> r = - ((-a) \circ (-b)) </tex> - эта же операция, посчитанная с округлением вверх. Значит, можно включить округление вниз до работы с интервалами и вернуть стандартный режим после нее, тогда много переключений не потребуется. Предполагается, что мы можем управлять округлением в операциях над вещественными числами. Стандарт IEEE 754 гарантирует такую возможность, но не все современные языки/архитектуры его выполняют. Например, согласно [http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf этому] материалу, вещественная арифметика в Java не соответствует стандарту IEEE 754 (в частности, не позволяет указывать правила округления). Поэтому на Java нельзя реализовать требуемую интервальную арифметику с использованием только примитивных типов double/float.