Почему при нахождении сум в прямом и обратном порядке ответ разный?
Почему при нахождении сумм в прямом (значение в переменной s1) и обратном порядке (s2) ответ разный?
#include <stdlib.h>
#include <stdio.h>
int main() {
float s1, s2;
long long int n;
s1 = 0.;
for (n = 1; n <= 100000000; n++) s1 += 1. / (n * n);
s2 = 0.;
for (n = 100000000; n >= 1; n--) s2 += 1. / (n * n);
printf("%.17lf\n", s1);
printf("%.17lf\n\n", s2);
system("pause");
return 0;
}
Ответы (1 шт):
ситуация следующая (все как говорит @avp) у float ограничена точность определённым кол-вом знаком после запятой, поэтому
1 + 10000000000000000000 = 10000000000000000000 (1e19)
точность у float в районе 7 знаков после запятой, поэтому у того же числа 10000000000000000000 в float входят только первые 7 цифр 1000000*************, а остальные не влияют никак на число, т.е.
999999999999 + 10000000000000000000 = 10000000000000000000 (1e19)
теперь что делают 2 ваших цикла:
первый цикл начинает складывать от большего числа к меньшему, в какой-то момент уже не имеет значения, что вы складываете - это не повлияет на результат
для float в вашем коде после n = 4096 все остальные слагаемые настолько малы относительно суммы, что не влияют на сумму
второй цикл начинает складывать от меньших чисел к большим, поэтому не учтенные в первом случае слагаемые после n = 4096 все таки в сумме образуют величину, которая влияет на итоговую сумму
поэтому и видим отличие
s1 1.64472532 float
s2 1.64493406 float
в первом случае поменьше, во втором побольше на ту самую сумму от n = 4096 до n = 100000000, а на самом деле где-то до n = 370728
Кстати у double мантисса гораздо больше (весь тип занимает 8 байт вместо 4 для float), поэтому результаты тоже будут разными по описанным выше причинам, но отличаться будут на меньшую величину
s1 1.6449340578345750 double
s2 1.6449340568482265 double
и в первом цикле слагаемые не учитываются уже только с n = 94906266