Re: Can anyone repeat this?

From: Bob (bsagusti_at_zeustech.com)
Date: 02/15/04


Date: Sun, 15 Feb 2004 10:17:58 -0500

Alexander is right on. Your float numbers are losing little tiny bits of
precision resulting in your condition failing. Can you do this with
integers? It seems like the values that you are incrementing and
decrementing by are linear, therefore you should be able to "alias" them
with integers just for comparison purposes. Although I'm not sure what
you're doing with this but another way would be to compare with a window
such as:

 if ( fabs(m_dSpinPos - m_dSpinInc) >= (m_dSpinLow + .000001) )

fabs() is the double absoulute value (floating point). Since you are
incrementing and decrementing by .01 (as represented by the compiler), you
should be protected from this problem by orders of magnitude. i.e. If you
are within +/- .000001 of (m_dSpinPos - m_dSpinInc), the condition is true.
As long as the rounding error is less than .000001 you will be ok. Since a
double goes out 15 digits in resolution in the VC++ compiler, this should
work.

Not a good idea to compare floating points like this though.

Hope I didn't confuse you... (or myself :) )

Bob

"Alexander Grigoriev" <alegr@earthlink.net> wrote in message
news:u8yJue38DHA.2480@TK2MSFTNGP10.phx.gbl...
> Read some books about numeric algorithms and floating point calculations.
> Find words "rounding error", "inexact representation". Think about it.
>
> "Michael" <NOSPAMmao@vnet.net> wrote in message
> news:euR9Ae18DHA.2604@TK2MSFTNGP10.phx.gbl...
> > This is really weird. The m_dSpinPos starts with a value of .01. When I
> > increment by .01 making the value .02 and then decrement by .01 the code
> > works. But when I perform 2 increments of .01 making the value .03 and
> then
> > decrement, the value will no go below .02.
> >
> > Here is the cpp code
> > if ( m_dSpinPos - m_dSpinInc >= m_dSpinLow )
> > {
> > m_dSpinPost -= m_dSpinInc;
> > }
> >
> > If anyone know assembler here it is.
> >
> > 1051: if ( m_dSpinPos - m_dSpinInc >= m_dSpinLow )
> > 0042F9DC mov eax,dword ptr [ebp-10h]
> > 0042F9DF mov ecx,dword ptr [ebp-10h]
> > 0042F9E2 fld qword ptr [eax+130h]
> > 0042F9E8 fsub qword ptr [ecx+138h]
> > 0042F9EE mov edx,dword ptr [ebp-10h]
> > 0042F9F1 fcomp qword ptr [edx+120h]
> > 0042F9F7 fnstsw ax
> > 0042F9F9 test ah,1
> > 0042F9FC jne CCustomCombo::OnLButtonDown+319h (0042fa19)
> > 1052: m_dSpinPos -= m_dSpinInc;
> > 0042F9FE mov eax,dword ptr [ebp-10h]
> > 0042FA01 mov ecx,dword ptr [ebp-10h]
> > 0042FA04 fld qword ptr [eax+130h]
> > 0042FA0A fsub qword ptr [ecx+138h]
> > 0042FA10 mov edx,dword ptr [ebp-10h]
> > 0042FA13 fstp qword ptr [edx+130h]
> > 1053: }
> >
> >
> > "Michael" <NOSPAMmao@vnet.net> wrote in message
> > news:%23Mh3YR18DHA.1948@TK2MSFTNGP12.phx.gbl...
> > > Actually, I've done that. Here is the real code that is failing:
> > > All vars are doubles.
> > > m_dSpinMin == .01
> > >
> > > // When m_dSpinPos == .02, it still skips the code
> > > if ( m_dSpinPos - .01 >= m_dSpinMin )
> > > {
> > > m_dSpinPos -= .01;
> > > }
> > >
> > > I've also tried this:
> > > m_dSpinInc == .01;
> > >
> > > if ( m_dSpinPos - m_dSpinInc >= m_dSpinMin )
> > > {
> > > m_dSpinPos -= .01;
> > > }
> > >
> > > and this
> > >
> > > double pos = m_dSpinPos - m_dSpinInc;
> > > if ( pos >= m_dSpinMin)
> > > {
> > > m_dSpinPos -= .01;
> > > }
> > > In this case when I break, pos == .01 and m_dSpinMin == .01 (according
> to
> > > the trace) but is still skps the code.
> > >
> > > Any other ideas?
> > >
> > >
> > >
> > > "Bob" <bsagusti@zeustech.com> wrote in message
> > > news:uZsUgQ08DHA.3380@tk2msftngp13.phx.gbl...
> > > > Instead of hard coding your conditions eg. .01,.02, try declaring
them
> > as
> > > > double vars, like the ones that you are comparing them to. I suspect
> > that
> > > > the double's representation in memory is slightly different than
your
> > hard
> > > > coded float.
> > > >
> > > >
> > > >
> > > > "Michael" <NOSPAMmao@vnet.net> wrote in message
> > > > news:OZDTdG08DHA.2416@TK2MSFTNGP10.phx.gbl...
> > > > > I've found this problem and I don't know what's going on. The
> snippet
> > > > below
> > > > > is just test code I included in my LeftButtonDown message. The
'up'
> > var
> > > is
> > > > a
> > > > > BOOL in the class and in initialized to TRUE, and the 'I' var is a
> > > double
> > > > > initialized to .01. When 'I' decrements down and is equal to .01,
> the
> > > > test
> > > > > condition (I >= .01) is not qualified and the code is skipped.
> > > > >
> > > > > if ( up )
> > > > > {
> > > > > I += .01;
> > > > > if ( I > .02 )
> > > > > up = FALSE;
> > > > > }
> > > > > else
> > > > > {
> > > > > I -= .01;
> > > > >
> > > > > if ( I >= 0.01 )
> > > > > {
> > > > > if ( I <= 0 )
> > > > > up = TRUE;
> > > > > }
> > > > > }
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>