В double
нет 30 цифр точности, поэтому использование %.30f
не слишком важно.
A double
имеет дробную часть, которая составляет около 52 двоичных битов. Или около 16 десятичных цифр.
Как уже упоминалось, плавающая точка не точна, и порядок операций может повлиять на результат.
Лучше увидеть, насколько далеки два результата, в процентах от «идеального» (то есть a
).
Я добавил это в вашу программу. Результаты:
Method 1: 1000099.9999766761902720
Method 2: 1000100.0000039888545871
dif: -0.0000273126643151
pct: -0.0000000027309933
Таким образом, разница составляет около 2 миллиардов 1 процента.
Но это немного вводит в заблуждение. Обратите внимание, что a
и b
отключены примерно на 0.00002
, но с целочисленной частью, использующей 7 цифр, это означает около 12 цифр.
Другими словами, два метода [для всех практических целей] эквивалентны в пределах ожидаемой точности и порядка операций.
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
int i,
n;
double a,
b,
c;
a = 0;
b = 0;
c = 0;
n = 1000000;
//Initialization
double vec[n];
for (i = 0; i < n; i++) {
vec[i] = 1.0001;
}
//Sum Method 1
for (i = 0; i < n; i++) {
a += vec[i];
}
//Sum Method 2
for (i = 0; i < n / 2; i++) {
b += vec[i];
}
for (i = n / 2; i < n; i++) {
c += vec[i];
}
b = c + b;
// ------------------------------------
printf("Method 1: %.16f\n", a);
printf("Method 2: %.16f\n", b);
double dif = a - b;
printf("dif: %.16f\n", dif);
double pct = dif / a;
pct *= 100;
printf("pct: %.16f\n", pct);
return 0;
}