Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Direct3D поддерживает несколько представлений с плавающей запятой. Все вычисления с плавающей запятой выполняются в соответствии с определённым подмножеством правил IEEE 754 для 32-разрядной одинарной точности.
32-разрядные правила с плавающей запятой
Существует два набора правил: те, которые соответствуют IEEE-754, и те, которые отклоняются от стандарта.
Соблюденные правила IEEE-754
Некоторые из этих правил являются одним вариантом, где IEEE-754 предлагает варианты выбора.
Деление на 0 производит +/-INF, за исключением 0/0, что приводит к naN.
Логарифм от (+/-) 0 дает -INF.
логарифм отрицательного значения (кроме -0) дает NaN.
Обратный квадратный корень (rsq) или квадратный корень (sqrt) отрицательного числа производит NaN.
Исключение равно -0; sqrt(-0) производит -0, а rsq(-0) производит -INF.
INF - INF = NaN
(+)INF / (+/-)INF = NaN
(+/-)INF * 0 = NaN
NaN (любой операнд) любое-значение = NaN
Сравнения EQ, GT, GE, LT и LE возвращают FALSE, если один или оба операнда являются NaN.
Сравнения игнорируют знак 0 (поэтому +0 равен -0).
Сравнение NE, когда один или оба операнда являются NaN, возвращает TRUE.
Сравнение любого значения, отличного от NaN, с +/-INF, возвращает правильный результат.
отклонения или дополнительные требования к правилам IEEE-754
IEEE-754 требует, чтобы операции с плавающей запятой давали результат, который является ближайшим представляемым значением к бесконечно точному результату, известному как округление до ближайшего четного.
Direct3D 11 и вверх определяют то же требование, что и IEEE-754: 32-разрядные операции с плавающей запятой создают результат, который находится в пределах 0,5 единицы последней точки (ULP) бесконечно точного результата. Это означает, что, например, оборудование может усечь результаты до 32-разрядного формата, а не выполнять округление до ближайшего четного числа, так как это приведет к ошибке не более 0,5 ULP. Это правило применяется только к добавлению, вычитании и умножению.
Более ранние версии Direct3D определяют более слабое требование, чем IEEE-754: 32-разрядные операции с плавающей запятой создают результат, который находится в пределах одного единицы последнего места (1 ULP) бесконечно точного результата. Это означает, что, например, аппаратное обеспечение может усечь результаты до 32-разрядных, а не выполнять округление до ближайшего чётного, так как это приведет к ошибке не больше, чем на один ULP.
Нет поддержки исключений с плавающей запятой, флагов состояния или триггеров.
Денормы преобразуются в ноль, сохраняющий знак, на входе и выходе любой математической операции с плавающей точкой. Исключения создаются для любой операции ввода-вывода или перемещения данных, которая не управляет данными.
Состояния, содержащие значения с плавающей запятой, такие как значения Viewport MinDepth/MaxDepth или BorderColor, могут быть предоставлены как денормальные значения и могут быть отброшены или сохранены перед их использованием оборудованием.
Операции минимум или максимум выбрасывают денормы для сравнения, но результат может или не может иметь сброшенные денормы.
Входные данные NaN для вычисления всегда приводят к NaN на выходе. Но точный битовый шаблон NaN не требуется для того, чтобы оставаться неизменным (если операция не является необработанной инструкцией перемещения , которая не изменяет данные.)
Операции min и max, для которых только один операнд является NaN, возвращают другой операнд в результате (вопреки правилам сравнения, которые мы рассмотрели ранее). Это правило IEEE 754R.
Спецификация IEEE-754R для операций с плавающей запятой min и max указывает, что если одно из входных данных в минимальное или максимальное значение является тихим значением QNaN, результатом операции является другой параметр. Рассмотрим пример.
min(x,QNaN) == min(QNaN,x) == x (same for max)Редакция спецификации IEEE-754R приняла другое поведение для min и max, если одно входное значение является "сигнальным" значением SNaN и значением QNaN:
min(x,SNaN) == min(SNaN,x) == QNaN (same for max)Как правило, Direct3D соответствует стандартам арифметики: IEEE-754 и IEEE-754R. Но в этом случае у нас есть отклонение.
Арифметические правила в Direct3D 10 и более поздних версиях не делают никаких различий между тихими и сигнальными значениями NaN (QNaN и SNaN). Все значения NaN обрабатываются одинаково. В случае min и max поведение Direct3D для любого значения NaN похоже на то, как QNaN обрабатывается в определении IEEE-754R. (Для полноты — если оба входных данных являются NaN, возвращается любое значение NaN.)
Другое правило IEEE 754R заключается в том, что min(-0,+0) == min(+0,-0) == -0 и max(-0,+0) == max(+0,-0) == +0, которое учитывает знак, в отличие от правил сравнения для знаковых нулей (как мы видели ранее). Direct3D рекомендует здесь поведение IEEE 754R, но не применяет его; Результат сравнения нулей может зависеть от порядка параметров, используя сравнение, которое игнорирует знаки.
x*1.0f всегда приводит к x (за исключением случаев, когда денормализованные числа подавлены).
x/1.0f всегда равен x (за исключением случаев, когда денормализованные числа удалены).
x +/- 0.0f всегда результат равен x (за исключением сброса денормализованных значений). Но -0 + 0 = +0.
Объединённые операции (такие как mad, dp3) дают результаты, которые не менее точны, чем худшее возможное последовательное упорядочивание вычисления несоединённого варианта операции. Определение наихудшего возможного упорядочивания в целях учёта допустимых отклонений не является фиксированным для данной объединённой операции; это зависит от конкретных значений входных данных. Отдельным шагам в необъединенном расширении допускается погрешность в 1 ULP (или в случае любых инструкций, для которых Direct3D допускает более высокий уровень погрешности, чем 1 ULP, разрешается использовать более высокий уровень).
Сплавленные операции соответствуют тем же правилам NaN, что и неисплавленные операции.
sqrt и rcp имеют допуск в 1 ULP. Инструкции шейдера на взаимное значение и взаимный квадратный корень, rcp и rsq, имеют свои отдельные требования к расслабленной точности.
Операции умножения и деления выполняются с 32-разрядной точностью с плавающей запятой (точность до 0,5 ULP для умножения и 1,0 ULP для обратного деления). Если x/y реализован напрямую, результаты должны иметь большую или равную точность, чем двухэтапный метод.
64-разрядные (двойная точность) правила с плавающей запятой
Аппаратные и дисплейные драйверы опционально поддерживают двойную точность с плавающей запятой. Чтобы указать поддержку, при вызове ID3D11Device::CheckFeatureSupport с D3D11_FEATURE_DOUBLESдрайвер устанавливает DoublePrecisionFloatShaderOps для D3D11_FEATURE_DATA_DOUBLES в значение TRUE. Затем драйвер и оборудование должны поддерживать все инструкции с двойной точностью для чисел с плавающей запятой.
Инструкции по двойной точности соответствуют требованиям к поведению IEEE 754R.
Требуется поддержка генерации денормализованных значений для данных двойной точности (без поведения округления до нуля). Аналогично, инструкции не интерпретируют денормализованные данные как числовое значение со знаком ноль; вместо этого, они учитывают само денормализованное значение.
16-разрядные правила с плавающей запятой
Direct3D также поддерживает 16-разрядные представления чисел с плавающей запятой.
Формат:
- 1 бит знака (s)в позиции бита MSB
- 5 бит предвзятой экспоненты (e)
- 10 бит дроби (f), с дополнительным скрытым битом
Значение float16 (v) следует следующим правилам:
- если e == 31 и f != 0, то v — NaN независимо от s
- если e == 31 и f == 0, то v = (-1)s*бесконечность (подписанная бесконечность)
- Если e находится в диапазоне от 0 до 31, то v = (-1)s*2(e-15)*(1.f)
- if e == 0 и f != 0, а затем v = (-1)s*2(e-14)*(0.f) (денормализованные числа)
- если e == 0 и f == 0, то v = (-1)s*0 (знаковый ноль)
32-разрядные правила с плавающей запятой также применимы к 16-разрядным числам с плавающей запятой, с учётом битовой структуры, описанной ранее. Ниже приведены исключения:
- Точность: Неприведённые операции с 16-разрядными числами с плавающей запятой создают результат, который является ближайшим представляемым значением к бесконечно-точному результату (округление до ближайшего чётного, в соответствии с IEEE-754, применяется к 16-разрядным значениям). 32-разрядные правила с плавающей запятой соответствуют точности в 1 ULP, 16-разрядные правила с плавающей запятой соответствуют точности в 0,5 ULP для несовмещённых операций и 0,6 ULP для совмещённых операций.
- 16-разрядные числа с плавающей запятой сохраняют денормы.
11-разрядные и 10-разрядные правила с плавающей запятой
Direct3D также поддерживает 11-разрядные и 10-разрядные форматы с плавающей запятой.
Формат:
- Нет бита знака
- 5 бит предвзятой экспоненты (e)
- 6 бит дроби (f) для 11-разрядного формата, 5 бит дроби (f) для 10-разрядного формата с дополнительным скрытым битом в любом случае.
Значение float11/float10 (v) соответствует следующим правилам:
- если e == 31 и f != 0, то v — NaN
- если e == 31 и f == 0, то v = +бесконечность
- значение e от 0 до 31, то v = 2(e-15)*(1.f)
- если e == 0 и f != 0, то v = *2(e-14)*(0.f) (денормализованные числа)
- если e == 0 и f == 0, то v = 0 (ноль)
32-разрядные правила с плавающей запятой также содержат 11-разрядные и 10-разрядные числа с плавающей запятой, скорректированные для битового макета, описанного ранее. К исключениям относятся:
- Точность: 32-разрядные правила с плавающей запятой соответствуют 0,5 ULP.
- 10/11-разрядные числа с плавающей запятой сохраняют денормализованные значения.
- Любая операция, результат которой - число меньше нуля, приравнивается к нулю.
Связанные разделы