Compartir a través de


Reglas de punto flotante

Direct3D admite varias representaciones de punto flotante. Todos los cálculos de punto flotante funcionan con un subconjunto definido de las reglas de punto flotante de precisión flotante IEEE 754 de 32 bits.

Reglas de punto flotante de 32 bits

Hay dos conjuntos de reglas: aquellos que se ajustan a IEEE-754 y los que se desvía del estándar.

Reglas de IEEE-754 respetadas

Algunas de estas reglas son una única opción en la que IEEE-754 ofrece opciones.

  • Dividir por 0 genera +/- INF, excepto 0/0, lo que da como resultado NaN.

  • el registro de (+/-) 0 genera -INF.  

    log de un valor negativo (distinto de -0) genera NaN.

  • La raíz cuadrada recíproca (rsq) o la raíz cuadrada (sqrt) de un número negativo produce NaN.  

    La excepción es -0; sqrt(-0) produce -0 y rsq(-0) genera -INF.

  • INF - INF = NaN

  • (+/-) INF / (+/-)INF = NaN

  • (+/-) INF * 0 = NaN

  • NaN (any OP) any-value = NaN

  • Las comparaciones EQ, GT, GE, LT y LE, cuando o ambos operandos son NaN devuelve FALSE.

  • Las comparaciones omiten el signo de 0 (por lo que +0 es igual a -0).

  • La comparación NE, cuando o ambos operandos es NaN devuelve TRUE.

  • Las comparaciones de cualquier valor que no sea NaN con +/- INF devuelven el resultado correcto.

Desviaciones o requisitos adicionales de las reglas IEEE-754

  • IEEE-754 requiere operaciones de punto flotante para generar un resultado que sea el valor representable más cercano a un resultado infinitomente preciso, conocido como redondeo a más cercano incluso.

    Direct3D 11 y versiones posteriores definen el mismo requisito que IEEE-754: las operaciones de punto flotante de 32 bits producen un resultado que está dentro de 0,5 unidades (ULP) del resultado infinito y preciso. Esto significa que, por ejemplo, el hardware puede truncar los resultados a 32 bits en lugar de realizar el redondeo al más cercano, ya que esto provocaría un error de al menos 0,5 ULP. Esta regla solo se aplica a la suma, resta y multiplicación.

    Las versiones anteriores de Direct3D definen un requisito más flexible que IEEE-754: las operaciones de punto flotante de 32 bits producen un resultado que se encuentra dentro de una unidad de último lugar (1 ULP) del resultado infinito-preciso. Esto significa que, por ejemplo, el hardware puede truncar los resultados a 32 bits en lugar de realizar el redondeo al más cercano, ya que esto provocaría un error de como máximo un ULP.

  • No hay compatibilidad con excepciones de punto flotante, bits de estado o capturas.

  • Los desnorms se vacían para conservar el signo cero en la entrada y salida de cualquier operación matemática de punto flotante. Las excepciones se realizan para cualquier operación de movimiento de datos o E/S que no manipule los datos.

  • Los estados que contienen valores de punto flotante, como Viewport MinDepth/MaxDepth o BorderColor, se pueden proporcionar como valores de desnorma y pueden o no vaciarse antes de que el hardware los use.

  • Las operaciones mínimas o máximas vacían los desnormas para la comparación, pero el resultado puede o no ser desnorm vaciado.

  • La entrada NaN en una operación siempre genera NaN en la salida. Pero el patrón de bits exacto de NaN no es necesario para mantenerse igual (a menos que la operación sea una instrucción de movimiento sin procesar, que no modifica los datos).

  • Las operaciones mínimas o máximas para las que solo un operando es NaN devuelven el otro operando como resultado (contrario a las reglas de comparación que hemos examinado anteriormente). Se trata de una regla IEEE 754R.

    La especificación IEEE-754R para las operaciones mínimas y máximas de punto flotante indica que si una de las entradas a min o max es un valor QNaN silencioso, el resultado de la operación es el otro parámetro. Por ejemplo:

    min(x,QNaN) == min(QNaN,x) == x (same for max)
    

    Una revisión de la especificación IEEE-754R adoptó un comportamiento diferente para min y max cuando una entrada es un valor SNaN de "señalización" frente a un valor QNaN:

    min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
    
    

    Por lo general, Direct3D sigue los estándares de aritmética: IEEE-754 e IEEE-754R. Pero en este caso, tenemos una desviación.

    Las reglas aritméticas de Direct3D 10 y versiones posteriores no distinguen entre valores NaN silenciosos y de señalización (QNaN frente a SNaN). Todos los valores NaN se controlan de la misma manera. En el caso de min y max, el comportamiento de Direct3D para cualquier valor NaN es como el modo en que QNaN se controla en la definición IEEE-754R. (Por integridad: si ambas entradas son NaN, se devuelve cualquier valor NaN).

  • Otra regla IEEE 754R es que min(-0,+0) == min(+0,-0) == -0 y max(-0,+0) == max(+0,-0) == +0, que respeta el signo, en contraste con las reglas de comparación para cero firmado (como se ha visto anteriormente). Direct3D recomienda el comportamiento IEEE 754R aquí, pero no lo aplica; se permite que el resultado de comparar ceros dependa del orden de los parámetros, utilizando una comparación que omite los signos.

  • x*1.0f siempre da como resultado x (excepto desnorm vaciado).

  • x/1.0f siempre da como resultado x (excepto desnorm vaciado).

  • x +/- 0.0f siempre da como resultado x (excepto desnorm vaciado). Pero -0 + 0 = +0.

  • Las operaciones fusionadas (como mad, dp3) producen resultados que no son menos precisos que el peor orden en serie posible de la evaluación de la expansión no fusionada de la operación. La definición de la peor ordenación posible, para el propósito de la tolerancia, no es una definición fija para una operación fusionada determinada; depende de los valores concretos de las entradas. Cada uno de los pasos individuales de la expansión sin fusión se permite 1 tolerancia ULP (o para las instrucciones que llama Direct3D con una tolerancia más lax que 1 ULP, se permite la tolerancia más lax).

  • Las operaciones fusionadas cumplen las mismas reglas naN que las operaciones no fusionadas.

  • sqrt y rcp tienen 1 tolerancia ULP. Las instrucciones de raíz cuadrada recíproca y recíproca del sombreador, rcp y rsq, tienen su propio requisito de precisión relajada independiente.

  • Multiplique y divida cada uno de ellos funciona en el nivel de precisión de punto flotante de 32 bits (precisión a 0,5 ULP para multiplicar, ULP de 1,0 para recíproca). Si x/y se implementa directamente, los resultados deben ser de mayor o igual precisión que un método de dos pasos.

Reglas de punto flotante de 64 bits (precisión doble)

Los controladores de hardware y visualización admiten opcionalmente el punto flotante de precisión doble. Para indicar compatibilidad, al llamar a ID3D11Device::CheckFeatureSupport con D3D11_FEATURE_DOUBLES, el controlador establece DoublePrecisionFloatShaderOps de D3D11_FEATURE_DATA_DOUBLES en TRUE. A continuación, el controlador y el hardware deben admitir todas las instrucciones de punto flotante de precisión doble.

Las instrucciones de precisión doble siguen los requisitos de comportamiento de IEEE 754R.

Se requiere compatibilidad con la generación de valores desnormalizados para los datos de precisión doble (sin comportamiento de vaciado a cero). Del mismo modo, las instrucciones no leen datos desnormalizados como cero con signo, respetan el valor de desnorm.

Reglas de punto flotante de 16 bits

Direct3D también admite representaciones de 16 bits de números de punto flotante.

Formato:

  • 1 bit de signo (s) en la posición del bit MSB
  • 5 bits de exponente sesgado (e)
  • 10 bits de fracción (f), con un bit oculto adicional

Un valor float16 (v) sigue estas reglas:

  • si e == 31 y f != 0, v es NaN independientemente de s.
  • si e == 31 y f == 0, v = (-1)s*infinity (infinito firmado)
  • si e está entre 0 y 31, v = (-1)s*2(e-15)*(1.f)
  • si e == 0 y f != 0, v = (-1)s*2(e-14)*(0.f) (números desnormalizados)
  • si e == 0 y f == 0, v = (-1)s*0 (cero firmado)

Las reglas de punto flotante de 32 bits también contienen números de punto flotante de 16 bits, ajustados para el diseño de bits descrito anteriormente. Entre las excepciones a esto se incluyen:

  • Precisión: las operaciones no fusionadas en números de punto flotante de 16 bits producen un resultado que es el valor representable más cercano a un resultado infinitamente preciso (redondeo al más cercano incluso, por IEEE-754, aplicado a valores de 16 bits). Las reglas de punto flotante de 32 bits se adhieren a la tolerancia de 1 ULP, las reglas de punto flotante de 16 bits se adhieren a 0,5 ULP para operaciones no fusionadas y 0,6 ULP para las operaciones fusionadas.
  • Los números de punto flotante de 16 bits conservan los desnormas.

Reglas de punto flotante de 11 y 10 bits

Direct3D también admite formatos de punto flotante de 11 y 10 bits.

Formato:

  • Sin bit de signo
  • 5 bits de exponente sesgado (e)
  • 6 bits de fracción (f) para un formato de 11 bits, 5 bits de fracción (f) para un formato de 10 bits, con un bit oculto adicional en cualquier caso.

Un valor float11/float10 (v) sigue las reglas siguientes:

  • si e == 31 y f != 0, v es NaN
  • si e == 31 y f == 0, v = +infinito
  • si e está entre 0 y 31, v = 2(e-15)*(1.f)
  • si e == 0 y f != 0, v = *2(e-14)*(0.f) (números desnormalizados)
  • si e == 0 y f == 0, v = 0 (cero)

Las reglas de punto flotante de 32 bits también contienen números de punto flotante de 11 y 10 bits, ajustados para el diseño de bits descrito anteriormente. Las excepciones son:

  • Precisión: las reglas de punto flotante de 32 bits se adhieren a 0,5 ULP.
  • Los números de punto flotante de 10/11 bits conservan los desnormas.
  • Cualquier operación que daría lugar a un número menor que cero se sujeta a cero.

Apéndices

Recursos

Texturas