сумма серий с использованием float

Я рассчитал первые 20 элементов серии —

введите описание изображения здесь

2 способами, 1 — вперед, 2 — назад. Для этого я сделал —

#include <iostream>
#include <math.h>
using namespace std;

float sumSeriesForward(int elementCount) {
float sum = 0;
for (int i = 0; i < elementCount; ++i) {
sum += (float) 1 / (pow(3, i));
}
return sum;
}

float sumSeriesBack(int elementCount) {
float sum = 0;
for (int i = (elementCount - 1); i >= 0; --i) {
sum += (float) 1 / (pow(3, i));
}
return sum;
}

int main() {
cout.precision(30);
cout << "sum 20 first elements - forward: " << sumSeriesForward(20) << endl;
cout << "sum 20 first elements - back: " << sumSeriesBack(20) << endl;
}

И я получил —

sum 20 first elements - forward: 1.5000001192092896
sum 20 first elements - back: 1.5

Может кто-нибудь объяснить, почему разница между этими двумя способами?

5

Решение

В общем случае числа с плавающей запятой не могут точно представлять значения. Когда вы оперируете значениями, ошибки распространяются. В вашем примере, когда вы вычисляете в обратном направлении, вы добавляете маленькие значения к все большим числам, и у вас есть хороший шанс, что сумма маленьких чисел до сих пор влияет на большее число. С другой стороны, когда вы вычисляете вперед, вы начинаете с больших чисел, и меньшие числа оказывают на них все меньшее влияние. То есть при суммировании вы всегда хотите подвести итог от наименьшего к наибольшему.

Просто подумайте о том, чтобы сохранить сумму в фиксированном количестве цифр. Например, оставьте 4 цифры и суммируйте эти числа сверху вниз и снизу вверх:

values   top to bottom   bottom to top
10.00      10.00            10.01
0.004      10.00            0.010
0.003      10.00            0.006
0.002      10.00            0.003
0.001      10.00            0.001

Числа с плавающей точкой работают точно так же, используя фиксированное число [двоичных] цифр.

10

Другие решения

Для повышения точности при суммировании чисел рассмотрим Алгоритм суммирования Кахана. Это значительно уменьшает ошибку по сравнению с очевидным подходом (включая суммирование чисел от наименьшего к наибольшему).

5

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector