Используя заданный вид чисел fp, скажем, float16, очень просто построить суммы с совершенно неверными результатами. Например, используя python/numpy:
import numpy as np
one = np.float16(1)
ope = np.nextafter(one,one+one)
np.array((ope,one,-one,-one)).cumsum()
# array([1.001, 2. , 1. , 0. ], dtype=float16)
Здесь мы использовали cumsum
для принудительного наивного суммирования. Если оставить в покое собственные устройства, numpy
использовал бы другой порядок суммирования, что дало бы лучший ответ:
np.array((ope,one,-one,-one)).sum()
# 0.000977
Вышеуказанное основано на отмене. Чтобы исключить этот класс примеров, допустим только неотрицательные термины. Для наивного суммирования все еще легко привести примеры с очень неправильными суммами. Следующие суммы 10 ^ 4 одинаковых терминов, каждый из которых равен 10 ^ -4:
np.full(10**4,10**-4,np.float16).cumsum()
# array([1.0e-04, 2.0e-04, 3.0e-04, ..., 2.5e-01, 2.5e-01, 2.5e-01],
dtype=float16)
Последний срок отклоняется в 4 раза.
Опять же, разрешение numpy
использовать парное суммирование дает намного лучший результат:
np.full(10**4,10**-4,np.float16).sum()
# 1.0
Можно построить суммы, которые превосходят парное суммирование. Выбрав eps ниже разрешения 1, мы можем использовать 1, eps, 0, eps, 3x0, eps, 7x0, eps, 15x0, eps,..., но это включает безумное количество терминов.
Мой вопрос: используя float16 и только неотрицательные термины, сколько терминов требуется, чтобы получить из парного суммирования результат, который по меньшей мере в 2 раза больше.
Бонус: тот же вопрос с "положительным" вместо "неотрицательного". Это вообще возможно?