floating point - online - implementación doble-doble resistente al modo de redondeo FPU
norma ieee 754 pdf (1)
Contexto: aritmética doble-doble
"Doble-doble" es una representación de números como la suma de dos números de precisión doble sin superposición en los significands. Esta representación aprovecha las implementaciones de hardware de doble precisión existentes para cálculos de "cuasi precisión cuádruple".
Una típica función C de bajo nivel en una implementación de doble doble puede tomar dos números de precisión doble a
y b
con |a| ≥ |b|
|a| ≥ |b|
y calcule el número doble-doble (s, e)
que representa su suma:
s = a + b;
e = b - (s - a);
(Adaptado de este artículo )
Estas implementaciones generalmente asumen el modo de redondeo a más cercano.
En el cálculo anterior, (s, e)
es un doble-doble normalizado solo debido a esta suposición. Sin él, con a == 0x1.0p60
, b == 1
, en modo redondeo hacia arriba, s
se calcula como 0x1.0000000000001p60
y e
un poco por encima de -0x0.0000000000001p60
. Su suma es igual a la suma matemática de b
pero sus significados se superponen.
Tome a == 0x1.0p120
y las sumas matemáticas de b
por un lado y s
y e
por otro lado ni siquiera coinciden.
Pregunta
¿Hay alguna manera de crear una biblioteca doble-doble con las mismas propiedades que tiene una biblioteca típica doble-doble en la ronda-a-más-incluso-par (es decir, relativamente rápida y relativamente precisa), pero que funciona independientemente del redondeo modo pasa a ser?
¿Esa biblioteca ya existe?
Contexto más general: funciones elementales redondeadas correctamente
Las implementaciones del tipo doble doble se usan para cálculos intermedios en la implementación de bibliotecas de funciones elementales redondeadas correctamente. Como resultado, las bibliotecas implementadas de esta manera tienden a fallar espectacularmente cuando se llama a una función mientras la FPU no está en el modo de redondeo a más cercano . Cambiar el modo de redondeo dentro de la función no es muy apetecible, por razones de rendimiento y porque una señal que llega mientras se está ejecutando la función dejaría a la FPU en el modo de redondeo a más cercano. La forma más simple que veo de tener funciones elementales rápidas y redondeadas correctamente que funcionen en cualquier modo de redondeo sería si de alguna manera se pudiera confiar en una aritmética de doble doble que funcionaba en cualquier modo de redondeo.
El artículo al que se refiere njuffa ofrece la siguiente función, con anotaciones muy similares a las de mi pregunta, excepto que lo que se denota fl (a+b)
simplemente se denota a+b
en mi pregunta:
Two−Sum−toward−zero2 (a, b)
if (|a| < |b|)
swap (a , b)
s = fl (a + b)
d = fl (s − a)
e = fl (b − d)
if(|2 ∗ b|<|d|)
s = a, e = b
return (s, e)
Esta es una solución muy clara para este cálculo elemental particular cuando se está en el modo de redondeo a cero. Hace esperar que algo sea posible para implementar una función elemental correctamente redondeada, al menos probando el modo de redondeo temprano y seleccionando algoritmos por separado, o quizás escribiendo un código muy cuidadoso que funcione para todos los modos de redondeo.