Получить потерянные цифры в операциях с плавающей запятой - PullRequest
0 голосов
/ 11 февраля 2020

Существует ли надежный и стандартный способ восстановления потерянной мантиссы в операциях с плавающей запятой?

IE

public float Sum(float a, float b, out float lostDigits)
{
    float sum = a + b;
    if(a > b)
        lostDigits = (sum - a) - b;
    else
        lostDigits = (sum - b) - a;
    return sum;
}

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Fast2Sum

С пояснением, приведенным ниже, алгоритм, показанный в этом вопросе, представляет собой алгоритм Fast2Sum , описанный TJ Dekker в 1971 году, хотя он впервые появился как часть «Компенсированного Уильяма Кахана». метод суммирования »в 1965 г. Если:

  • основание с плавающей запятой равно 2 или 3, доступны
  • субнормальные числа,
  • каждая операция выполняется с округлением -в ближайший,
  • каждая операция выполняется с одинаковой точностью с плавающей запятой, и
  • sum не переполняется до бесконечности,

затем сумма действительных чисел sum и lostDigits равна сумме действительных чисел a и b, согласно Жан-Мишелю Мюллеру и др. в Справочнике с плавающей точкой Arithmeti c, 2010, пункт 4.3.1, «Алгоритм Fast2Sum».

Предостережение

Fast2Sum требует, чтобы показатель из a будет, по крайней мере, таким же большим, как показатель из b. Таким образом, тест a > b неадекватен, если a или b могут быть отрицательными. fabs(a) > fabs(b) будет достаточно для обеспечения работоспособности предложения затем , но это не гарантирует работоспособность предложения else . Вместо этого Мюллер и др. дают алгоритм 2Sum , который работает для любых осей и любых a и b, которые являются нормальными числами, и при условии, что переполнения или в радиациях больше чем 2, underflow 1 :

s  = a  + b;
ap = s  - b;
bp = s  - ap;
ad = a  - ap;
bd = b  - bp;
t  = ad + bd;

Сноска

1 Как отмечает aka.nice, не похоже, что underflow будет проблема, если поддерживаются субнормалы. Поскольку сложение и вычитание не включают в себя какие-либо цифры, более низкие по положению, чем цифры в их операндах, недостаточный результат до субнормальных результатов не должен иметь различий в вычислениях по сравнению с теми же операциями, масштабируемыми во избежание потери значения. В этом ответе я сообщил о заявлениях, сделанных Мюллером и др. . Возможно, код работает с недостаточными значениями, если поддерживаются субнормалы, но я не решаюсь изменить Мюллера и др. без тщательного рассмотрения.

0 голосов
/ 11 февраля 2020

Да, есть. Это базовая c операция, используемая при суммировании Кахана , и она очень похожа на ваш код. Он работает следующим образом:

assert(a >= b)
sum = a + b
bPrime = sum - a
resid = b - bPrime

a + b (точное значение, а не вычисленное количество) теперь точно равно sum + resid (опять же, точное значение). Конечно, вы не можете напрямую использовать это: вычисление sum+resid в контексте с плавающей запятой даст просто sum. Идея, лежащая в основе суммирования Кахана, состоит в том, чтобы повторно ввести остаток при добавлении последующих терминов. Другие подходы просто сохраняют значения как неявную сумму набора чисел с плавающей запятой с непересекающимися мантиссами.

...