# How to fix floating point artifacts in StdDev calculation?

I trying to calculate standard deviation with a next method:

``````private static double? StdDev(IReadOnlyCollection<double> items) {
if(items == null) {
throw new ArgumentNullException("items");
}//if

var count = items.Count;
if(count == 0 || count == 1) {
return null;
}//if

var sum = 0d;
var sqrsum = 0d;
foreach(var item in items) {
sum += item;
sqrsum += item * item;
}//for

var average = sum / count;
var stddev = Math.Sqrt((sqrsum - count * average * average) / (count - 1));
return stddev;
}
``````

Sometimes, the expression "sqrsum - count * average * average" is less than 0 and Math.Sqrt returns NaN. For example, in this case:

``````private static void Main() {
var data = Enumerable.Repeat(86.399999999999991, 3).ToList();
var stddev = StdDev(data);
Console.WriteLine("StdDev = " + stddev);
}
``````

How can I fix this cases in my code? should I use Math.Abs(sqrsum - count * average * average) or should I round something?

• You can subtract average from the item before squaring inside your loop, and then just take sqrt of sum/N in the end. Apr 30, 2015 at 8:59
• @folkol Thanks, but I want to have a single iteration of items. Apr 30, 2015 at 9:03
• Then I guess you will be stuck with numeric errors like that. You can always check for negative numbers and return 0 before sqrt:ing. Apr 30, 2015 at 9:05
• @folkol Thanks! May be yet another "if" is not a bad. Apr 30, 2015 at 9:07
• No, it might work fine :) (Although, the convention for numeric methods of calculating std is doing the subtraction before squaring... For the reasons that you are experiencing above.) Apr 30, 2015 at 9:09

I think the following code will work for you to calculate the standard deviation.

``````    private object StdDev(IReadOnlyCollection<double> items)
{
if (items == null)
{
throw new ArgumentNullException("items");
}//if

var count = items.Count;
if (count == 0 || count == 1)
{
return null;
}//if

var sum = 0d;
var sqrsum = 0d;
foreach (var item in items)
{
sum += item;
sqrsum += item * item;
}//for

var average = sum / count;

double deviation = 0d;
for (int i = 0; i < items.Count(); i++)
{
deviation += (items[i] - average) * (items[i] - average);
}
deviation = deviation / (count - 1);

var stddev = Math.Sqrt(deviation);
return stddev;
}
``````
• Thanks, but I want to have a single iteration of items. "Items" can be a very big list. And, when I know a count of items, "items" can be an IEnumerable<> that iterated ones. Apr 30, 2015 at 9:24
• Actually there was only one miss in your code and that is the calculation of deviation variable(see in my code). Apr 30, 2015 at 9:26