Эквивалент расширения продукта с плавающей точкой

В плавающей точке IEEE 754 возможно, что

a*(b-c) != a*b-a*c // a, b, c double

Таким образом, разложение продукта не гарантируется равным нерасширенному произведению.

Но как насчет этого:

a*(b1+b2+...+bn) == a*b1+a*b2+...+a*bn // b1==b2==...==bn

Когда все b равны, гарантирована ли эквивалентность (в случае отсутствия недо-/переполнения)? Есть ли разница, если во время компиляции известно равенство b или нет?

Edit:

Это не - см. Эрик Постщил и Паскаль Куок.

Но, возможно, имеет более слабое утверждение?:

   (1.0/n)*(b1+b2+...+bn) <= 1.0
&& (1.0/n)*b1+(1.0/n)*b2+...+(1.0/n)*bn <= 1.0

// when all b<=1.0 and n integral double but not power of 2
// so that 1.0/n not exactly representable with base-2 floating point

Я просто задаюсь вопросом, можете ли вы гарантировать, что среднее значение набора данных не превышает некоторого значения, которое также не будет превышено каждым значением данных независимо от того, как вы вычисляете среднее значение (сначала добавляете и деляете, или добавляете каждый значение разделено).

Edit2:

Хорошо, && не выполняется. См. Eric Postpischil и David Hammen:

average of nine 1.0 -> only first condition is true, second exceeds.
average of ten 1.0/3 -> only second condition is true, first exceeds.

Является ли тогда оптимальным методом вычисления среднего значения верхнего ожидаемого предела набора данных? Или также размер (что означает n) набора данных? Или нет оптимального метода, который, безусловно, существует?

Ответ 1

Даже исключая переполнение и недоиспользование, результаты могут отличаться.

.3 * (.3+.3+.3) составляет 0.269999999999999962252417162744677625596523284912109375, тогда как .3*.3 + .3*.3 + .3*.3 - это 0.270000000000000017763568394002504646778106689453125 (когда оба оцениваются с помощью правил IEEE-754 и 64-разрядной двоичной с плавающей запятой).

Относительно вопросов, добавленных в обновление:

Есть два вопроса, один из которых спрашивает, может ли вычисленное среднее из набора чисел не превосходить одного. Как указывает Дэвид Хэммон, вычисляя среднее значение девяти 1 с как 1./9*1 + 1./9*1 + 1./9*1 + 1./9*1 + 1./9*1 + 1./9*1 + 1./9*1 + 1./9*1 + 1./9*1, производит 1.0000000000000002220446049250313080847263336181640625.

Другой спрашивает, может ли вычисленное среднее значение набора превышать все числа в наборе. Это надмножество первого вопроса, но вот пример, использующий другой расчет среднего значения:

Пусть b = 1./3 (это 0,3333333333333333314829616256247390992939472198486328125).

Тогда 1./10 * (b+b+b+b+b+b+b+b+b+b) равно 0,333333333333333337034076748750521801412105560302734375, что больше, чем b.

Ответ 2

IEEE 754 не слишком разбирается в деталях языка. В частности, детали, такие как "время компиляции", не указаны. Это даже не имеет смысла для некоторых языков.

Проще всего понять, когда у вас есть промежуточная бесконечность. Предположим, что sum(b)==INF, едва, но a равно 0,5. Результатом a*sum(b) остается INF. Однако, сначала умножая, последующее добавление больше не переполняется.

Ответ 3

Но, возможно, имеет более слабое утверждение?:

(1.0/n)*(b1+b2+...+bn) <= 1.0
&& (1.0/n)*b1+(1.0/n)*b2+...+(1.0/n)*bn <= 1.0

Нет. Например, это утверждение терпит неудачу на моем компьютере с n = 9 и b i= 1.0.

Я просто задаюсь вопросом, можете ли вы гарантировать, что среднее значение набора данных не превышает некоторого значения, которое также не будет превышено каждым значением данных независимо от того, как вы вычисляете среднее значение (сначала добавляете и деляете, или добавляете каждый значение разделено).

И снова ответ отрицательный. Корреляция E [(X-Xbar) * (Y-Ybar)]/(sigma_x * sigma_y) между двумя случайными величинами всегда должна быть между -1.0 и 1.0. Однако, если вы вычислите статистику для двух совершенно коррелированных (или совершенно антикоррелированных) случайных величин, вы часто увидите корреляцию, которая немного больше +1 (или немного меньше -1).