Наткнулся на статью про то, как быстро и корректно складывать числа с плавающей запятой (ссылка будет в конце).
Общая проблема в том, что из-за того, что дробные числа хранятся в примитивных типах не точно, может возникать некоторая потеря точности (сорян за тавтологию) при арифметических операциях. Например когда складываешь большое число с маленьким, маленькое вполне может никак не изменить ответ, т.к. оно с точки зрения хранения чисел "пренебрежимо мало" (ну или нужное число не может быть представлено дробным число) Вопрос в том, как наиболее точно сложить какое-то множество чисел.
Пусть у вас есть какой-то массив числе с плавающей запятой. Конечно мы можем сложить числа просто подряд:
std::vector<float> v = Get();
float ans = 0.0;
for (int i = 0; i < v.size(); ++i) {
ans += v[i];
}
Но тогда у вас в какой-то момент может получится огромное число и следующее добавление маленького легко потеряется из-за погрешности.
А можем отсортировать вектор чисел перед суммой! Тогда мы будем накапливать сумму и при добавлении следующего числа по возрастанию оно может быть сравнимо с текущей суммой (хотя конечно зависит от данных, т.к. если все ваши числа это 1 + x_i, где x_i -- последовательность очень маленьких возрастающих чисел, то в какой-то момент большая сумма скушает этот 1 + eps).
Можно сделать лучше. Например закинуть все числа в кучу и попарно складывать два самых маленьких числа, возвращая результат обратно. Это может работать лучше, т.к. теперь мы ни в какой момент не будем складывать сумму большого количества элементов с одним небольшим.
Дальше развивать не буду. Прочитаете в статье: оригинал и перевод.
Кстати когда-то у студентов на пару лет младше в унике видел фановый контест в рамках одной из дисциплин, где нужно было найти сумму чисел наиболее точно (авторское решение, естественно, на длинке python). Первое место забрал чувак с суммой Кэхена.
Ну и мем из молодости: плавающая запятая.
