Ответ 1
Пусть y/d
- точная операция, а q=rnd(y/d)
- результат, округленный до ближайшего поплавка.
Тогда истинная ошибка, умноженная на d, равна rt=(rnd(y/d)-y/d)*d=q*d-y
, а операция, которую мы выполнили с fmadd, равна r=rnd(q*d-y)
Почему q*d-y
является точным (fmadd не делает окончательного округления) менее понятно для объяснения, но скажем, что q*d
имеет ограниченное количество бит (<nbits(q)+nbits(d)
), показатель степени y
равен показателю q*d
( +/- 1), а поскольку ошибка |rt|<0.5*ulp(q)*d
, это означает, что первые nbits(q)
исчезают... Это отвечает на вопрос 1.
So q*1e98 - y = r
, где |r|*2^1074 <= 0.5e98 < 5*10^98
(второе неравенство повезло)
q*(10^98) - y = r + (10^98-1e98)*q
где |10^98-1e98|*q*2^1074 <= 0.5e95
(предполагая точность не менее 15 цифр, log(2^53)/log(10) > 15
)
Итак, вы спрашиваете, |q*(10^98)-y|*2^1074>5*10^97
У вас есть приближение |q*(10^98)-y|
, которое r+1e98_2*q
Так как |r| < 5*10^98
и |r+(10^98-1e98)*q|<|r|
, если знаки противоположны, я думаю, что это положительно отвечает на вопрос 2. Но я не был бы так уверен, если бы 1e98_2 были < 0.
Если r
и 1e98_2
имеют один и тот же знак, он может превышать 5*10^97
, поэтому ваша дальнейшая обработка с обсуждением r3 = 1e98_2*q + r
по сравнению с h=0.5e98*2^-1074
Для вопроса 3, на первый взгляд, я бы сказал, что две вещи могут привести к сбою алгоритма:
-
1e98_2
не является точным (10^98-1e98-1e98_2 = -3.6e63
прибл.) -
и
h
неht=0.5*10^98*2^-1074
, но немного меньше, как мы видели выше.
Истинная ошибка r3t
примерно равна (1e98_2-3e63)*q + r < r3
(и нам интересен только случай, когдa > 0, так как 1e98_2 > 0).
Таким образом, аппроксимация ошибки r3, падающей выше аппроксимированной связи h, когда истинная ошибка r3t ниже истинной связи ht, может привести к неправильному округлению. Возможно ли, и если да, как часто возникает ваш вопрос 3?
Чтобы смягчить выше риск неравенства, вы попытались усечь величину r3, таким образом r3 <= 1e98_2*q + r
. Я чувствовал себя немного уставшим, чтобы выполнить истинный анализ границ ошибок...
Итак, я просмотрел ошибку, и первый неудачный пример, который я нашел, был 1.0000000001835e110 (я предполагаю, что правильно округлено до ближайшего двойника, но на самом деле это 1000000000183.49999984153799821120915424942630528225695526491963291846957919215885146546696544423465444842668032e98).
В этом случае r
и 1e98_2
имеют один и тот же знак, а
-
(x/1e98) > 1000000000183.50000215
-
q
Значение таким образом округляется до1000000000184
-
r3>h
(r3*2^1074
составляет около 5.000001584620017e97), и мы неправильно увеличилиq+s
, когда он должен былq-s
, определенно ошибка.
Мои ответы:
-
да,
r=fmadd(q * 1e98 - y)
составляет ровно 1e98 * (ошибка во время деления), но мы не заботимся о делении, это просто дает предположение, что считается, что вычитание является точным. -
да, знак правильный, потому что
|r| < 5*10^98
и|r+(10^98-1e98)*q|<|r|
, если знаки противоположны. Но я не был бы так уверен, если бы 1e98_2 были < 0. -
Взяв первый неудачный пример
(1.0000000001835e110 - 1.0e110)/1.0e110 ulp -> 1.099632e6
, очень наивная гипотеза заключалась бы в том, чтобы сказать, что 1 случай из миллиона, r3 падает на h... Так как раз q + s исправлено в qs, возникновениеr3>h
, в то время какr3t<ht
намного меньше 1/1 000 000 в любом случае... в интересующем диапазоне больше 10 ^ 15 удвоений, так что считайте, что это не серьезный ответ... -
Да, обсуждение выше касается исключительно предположения q, независимо от способа его создания, и вычитание в 1. будет по-прежнему точным...