Template:Пример суммирования с округлением

From SunFlurry wiki
Jump to: navigation, search

Данный пример показывает, как можно избежать накопления неточности при суммировании большого количества вещественных чисел, если известна точность их представления (количество знаков в мантиссе).

aTab:=Tab.Create("b1");
For i:=1 To 1000000 Do
  aTab.AddLine("b1",1.33552);
EndDo;

Message(NumberToStr(aTab.Sum("b1"),1));
Message(NumberToStr(aTab.Sum("b1",0,1,aTab.Size(),5),1));
//В первом случае будет выведено: "1335519.99999998508"
//Во втором случае будет выведено: "1335520"
//Сложение миллиона чисел (подобранных с целью увеличения неточности) дает неточность большую, чем 1E-8, при этом, сами числа имеют точность 1E-5, 
//  эти значения уже сравнимы между собой, поэтому при очень большом количестве операций над числами с длинными но точными мантиссами можно получить ошибку в последних знаках результата.
//Для вещественных чисел с мантиссами любой точности это не имеет большого значения, так как такие числа в основном используются для нахождения статистических, 
//  средних значений или при рисовании графиков, где точность результата ограничивается условием и обычно не превышает нескольких знаков после точки.
//По времени выполнения: функция сложения без округления была выполнена (i5) за 9.8 мс., с округлением 23.1 мс., т.е. разница по времени выполнения чуть больше 2 раз, 
//  что не очень много, учитывая высокую скорость работы таких функций.