Ваши два алгоритма эквивалентны. Единственной разницей во время исполнения будет знак c
. Причина, по которой он использует сложение, заключается в том, что в версии Кахана c
представляет ошибку, которая обычно является правильной минус вычисленное значение.
В том смысле, что в скобках указан порядок операций, скобки абсолютно необходимы. Фактически, именно они заставляют работать этот алгоритм!
Когда вычитание является левоассоциативным, как это имеет место в большинстве языков, a - b - c
оценивается как (a - b) - c
, поэтому оба значения одинаковы. Но вычитание в алгоритме Кахана равно a - (b - c)
, и это должно не быть оценено как a - b + c
.
Сложение и вычитание с плавающей точкой не являются ассоциативными. Для выражений, эквивалентных стандартной арифметике, вы можете получить разные результаты в зависимости от порядка выполнения операций.
Для ясности давайте работать с точностью до 3 десятичных знаков. Это означает, что если мы получаем результат с 4 цифрами, мы должны округлить его.
Теперь сравните (a - b) - c
с математически эквивалентным a - (b + c)
для некоторых конкретных значений:
(998 - 997) - 5 = 1 - 5 = -4
с
998 - (997 + 5) = 998 - Round(1002)
= 998 - 1000 = -2
Итак, второй подход менее точен.
В алгоритме Кахана t
и sum
обычно будут относительно большими по сравнению с y
. Таким образом, вы часто сталкиваетесь с ситуацией, как в примере выше, где вы получите менее точный результат, если не будете выполнять операции в правильном порядке.