Standard deviation of decimal numbers

Jill Gallaher

Jill Gallaher (view profile)

님이 질문을 제출함. 26 Jun 2019
최근 활동 Jill Gallaher

Jill Gallaher (view profile)

님이 댓글을 추가함. 26 Jun 2019
David Goodmanson

David Goodmanson (view profile)

님이 답변을 채택함.
Why is it that when I take the standard deviation of a list of equal numbers less than one that I get a non-zero standard deviation? Further, I get different standard deviations depending on the length of the list? I am looping through many lists of many sizes that are mainly non-zero standard deviations, so it often maybe doesn't matter. However, I'm calculating the fraction of one standard deviation over the other in this case, and it can result in orders of magnitude difference when it should be zero. I can get around this by checking for stds less than a non-zero amount, but I'm wondering why this is so. In other code, I've assumed that my conditional statements for dividing by zero was enough. Any ideas?
In other words, my thoughts are that this code should give all zeros:
x1=1*ones(100,1);
std(x1)
x2=1*ones(1000,1);
std(x2)
x1=0.1*ones(100,1);
std(x1)
x2=0.1*ones(1000,1);
std(x2)

로그인 to comment.

답변 수: 2

Answer by David Goodmanson

David Goodmanson (view profile)

on 26 Jun 2019

Hi Jill,
This is just the usual numerical 'error' due to the limitations of floating point arithmetic.
std(.1*(ones(1,1e5)))
ans = 2.5202e-14
It's not zero, but it's still pretty small, considering that 100,000 numbers are involved. If you try format hex, which shows what's taking place in memory,
format hex
.1
ans = 3fb999999999999a
it doesn't take an expert in floating point to see that there is some compromise rounding going on. Most numbers with decimal digits are like this. On the other hand,
>> std(.125*(ones(1,1e5)))
ans = 0000000000000000
and you get zero, because .125 = 1/8 has an exact binary representation:
.125
ans = 3fc0000000000000

Jill Gallaher

Jill Gallaher (view profile)

26 Jun 2019
That makes sense. Thanks.

로그인 to comment.

gonzalo Mier

gonzalo Mier (view profile)

님의 답변 26 Jun 2019

The error you are obtaining is less than 1e-15, which is 0 in practice. If you want to consider this case, you can use a threshold of 1e-10 for example like
if abs(x)<threshold
x=0;
end
Usually this kind of problems appear due to finite precision doing the calculus. One ore two bits of difference in a 32 bits variable creates small errors like this.

로그인 to comment.