В типичных реализациях с плавающей запятой результат одной операции создается так, как если бы операция была выполнена с бесконечной точностью, а затем округляется до ближайшего числа с плавающей запятой.
Сравните и b + a : результат каждой операции, выполненной с бесконечной точностью, одинаков, поэтому эти идентичные результаты с бесконечной точностью округляются одинаковым образом. Другими словами, сложение с плавающей точкой коммутативно.а + бб + а
Возьмем : b - число с плавающей точкой. Для двоичных чисел с плавающей запятой 2 b также является числом с плавающей запятой (показатель степени на единицу больше), поэтому b + b добавляется без ошибок округления. Затем добавляется a к точному значению b + b . Результатом является точное значение 2 b + a , округленное до ближайшего числа с плавающей запятой.б + б + аб2 бб + бaб + б2 б + а
Возьмем : добавлено a + b , и будет ошибка округления r , поэтому мы получим результат a + b + r . Добавьте b , и в результате получите точное значение 2 b + a + r , округленное до ближайшего числа с плавающей запятой.а + б + ба + брa + b + rб2 б + а + р
Так в одном случае , округлые. В другом случае 2 b + a + r , округлено.2 б + а2 б + а + р
PS. Для двух конкретных чисел и b оба вычисления дают один и тот же результат или нет, зависит от чисел и от ошибки округления в вычислениях a + b , и их обычно трудно предсказать. Использование одинарной или двойной точности в принципе не имеет значения для проблемы, но поскольку ошибки округления различны, будут значения a и b, где с одинарной точностью результаты равны, а с двойной точностью - нет, или наоборот. Точность будет намного выше, но проблема в том, что два выражения математически одинаковы, но не одинаковы в арифметике с плавающей точкой, остается неизменной.aба + б
PPS. В некоторых языках арифметика с плавающей запятой может выполняться с более высокой точностью или с большим диапазоном чисел, чем задано фактическими утверждениями. В этом случае было бы гораздо более вероятно (но все еще не гарантировано), что обе суммы дают один и тот же результат.
PPPS. Комментарий спросил, должны ли мы спрашивать, равны ли числа с плавающей запятой или нет вообще. Абсолютно, если вы знаете, что делаете. Например, если вы сортируете массив или реализуете набор, вы попадаете в ужасные неприятности, если хотите использовать какое-то понятие «примерно равный». В графическом пользовательском интерфейсе вам может потребоваться пересчитать размеры объекта, если размер объекта изменился - вы сравниваете oldSize == newSize, чтобы избежать этого пересчета, зная, что на практике у вас почти никогда не бывает почти одинаковых размеров, и ваша программа верна даже если есть ненужный пересчет.