Ваша предпосылка ошибочна. x*(a + b)
, (в целом) не менее точен, чем x*a + x*b
. Фактически, это часто будет более точным, потому что он выполняет только две операции с плавающей запятой (и, следовательно, вызывает только две ошибки округления), тогда как последний выполняет три операции.
Если вы знаете что-то об ожидаемом распределении значений для x
, a
и b
априори, вы можете принять обоснованное решение, но компиляторы почти никогда не имеют доступа к информации такого типа.
Кроме того, что, если человек, пишущий программу, на самом деле имел в виду x*(a+b)
, а конкретно хотел именно те округления, которые вызваны этой конкретной последовательностью операций? Подобные вещи на самом деле довольно распространены в высококачественных численных алгоритмах.
Лучше делать то, что написал программист, а не то, что, как вы думаете, он, возможно, намеревался.
Редактировать - Пример, иллюстрирующий случай, когда преобразование, которое вы предложили, приводит к катастрофической потере точности: предположим,
x = 3.1415926535897931
a = 1.0e15
b = -(1.0e15 - 1.0)
Затем, оценивая в double
получаем:
x*(a + b) = 3.1415926535897931
но
x*a + x*b = 3.0