Как наивная оценка многочленов плоха для точности?

В этом обзоре кода ответ:

https://codereview.stackexchange.com/a/59405/11633

Я нашел следующее (вложенная цитата впереди!):

позвольте мне процитировать замечательную книгу численных рецептов в C++ (но также применимо)

мы предполагаем, что вы знаете достаточно, чтобы никогда не оценивать многочлен таким образом:

p=c[0]+c[1]*x+c[2]*x*x+c[3]*x*x*x+c[4]*x*x*x*x;

или (что еще хуже!),

p=c[0]+c[1]*x+c[2]*pow(x,2.0)+c[3]*pow(x,3.0)+c[4]*pow(x,4.0);

придут (компьютер) революция, все лица, признанные виновными в таком преступном поведении, будут казнены, а их программы-нет!

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

есть две причины не делать этого: точность и производительность. Правильный способ оценки многочлена таков:

-t * (0.319381530  +  t * (-0.356563782 + t * (1.781477937 + t * (-1.821255978 + 1.330274429 * t))))

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

Я нашел книгу, но не эту информацию нигде вокруг цитируемого бита.

1 ответов


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

Он имеет еще одно преимущество, когда у вас есть очень большие или малые числа. Предполагая, что все коэффициенты находятся в одном и том же порядке величины, все члены имеют один и тот же порядок. Если вы оцениваете полином порядка 5 с коэффициентами вокруг 1 при x=0.1, простым способом будет добавление 0.1 к 10^-5, теряя точность.

кстати, это называется Горнера.