Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Expressions not evaluating as expected

0 views
Skip to first unread message

Alan Secker

unread,
Jun 11, 2008, 12:45:54 PM6/11/08
to
The extract below is in a do loop. It gets numerical values
from timeledg->evaluate and timeledg->disburse only when
TICK == "M" and plonks them into local variables nEval and nDisb.

If the nEval + nDisb does not equal zero, it prints the
result. However as you can see by the two lines ahead of
the if statement, it was not always being bypassing the if
statement when the two variables DID equal zero.

The two statements helped but I still end up with abut eight
zero items out of about 200 when there should be none.

|Where am I going wrong:

ntlrec := timeledg->(recno())

sum timeledg->evaluate, ;
timeledg->disburse to nEval, nDisb FOR ;
timeledg->tick == "M";
WHILE timeledg->clientid == name->clientid

timeledg->(dbgoto (ntlrec))

*: Clipper doesn't seem to like comparing numbers whose
*: underlying string length is different

nEval := val ( trim ( str ( nEval )))
dDisb := val ( trim ( str ( nDisb )))

if nEval + nDisb != 0

// Print Report line befotre zeroing nEval and nDisb

nEval := 0
nDisb := 0

endif

I have only tried this in Clipper so far as I don't yet need it in
Linux.

Stephen Quinn

unread,
Jun 12, 2008, 4:01:47 AM6/12/08
to
Alan

> *: Clipper doesn't seem to like comparing numbers whose
> *: underlying string length is different

So make them the same length (why compare strings though?)
Eg
val( str( nEval,8,2 ) )
val( str( nDisb,8,2 ) )

> The two statements helped but I still end up with abut eight
> zero items out of about 200 when there should be none.

Perhaps it's a rounding error which is causng the test to fail

Try
if nEval + nDisb >= 0.01

CYA
Steve


Alan Secker

unread,
Jun 12, 2008, 5:13:31 AM6/12/08
to
Stephen Quinn wrote:

> Alan
>
>> *: Clipper doesn't seem to like comparing numbers whose
>> *: underlying string length is different
> So make them the same length (why compare strings though?)
> Eg
> val( str( nEval,8,2 ) )
> val( str( nDisb,8,2 ) )

I tried this. It made no difference.


>
>> The two statements helped but I still end up with abut eight
>> zero items out of about 200 when there should be none.
> Perhaps it's a rounding error which is causng the test to fail

All dbf value fields are held to 2 decimal places. So while some of the
figures ending up in them may be the result of 'X' or '/' functions the
results can only be held to two decimal places. This program makes no
calculations other than addition. So I think it is unlikely. After all how
can a two decimal figure ever become less than 0.01? Surely it would show
up in the values shown by one of the two variables?

>
> Try
> if nEval + nDisb >= 0.01
>
> CYA
> Steve

I'll keep banging my head against a wall. <G>

Regards

Alan


Vitomir Cvitanovic

unread,
Jun 12, 2008, 6:01:05 AM6/12/08
to
Alan,

In Clipper we don't have explicit numeric declaration so result of addition
of two numbers have unpredictable number of decimals (FP).
If you like to check it out try something like:
? (nEval + nDisb)* 10000000
I think you will see the difference.

So, if you expect that numbers contain only two decimal digits I would test
it like:
IF ABS(nEval+nDisb) > 0.001 // nEval + nDisb != 0


// Print Report line befotre zeroing nEval and nDisb

Actualy, I'm using this way to compare if result is 0.

Regards,

Vito


"Alan Secker" <al...@asandco.co.uk> wrote in message
news:SfSdnbcbpsN7d83V...@pipex.net...

diogenes

unread,
Jul 3, 2008, 3:07:10 PM7/3/08
to
On Jun 12, 3:01 am, "Vitomir Cvitanovic" <vito_rem@mcfrontis_rem.hr>
wrote:

> Alan,
>
> In Clipper we don't have explicit numeric declaration so result of addition
> of two numbers have unpredictable number of decimals (FP).
> If you like to check it out try something like:
> ? (nEval + nDisb)* 10000000
> I think you will see the difference.
>
> So, if you expect that numbers contain only two decimal digits I would test
> it like:
> IF ABS(nEval+nDisb) > 0.001        // nEval + nDisb != 0
>             // Print Report line befotre zeroing nEval and nDisb
>
> Actualy, I'm using this way to compare if result is 0.
>
> Regards,
>
> Vito
>
> "Alan Secker" <a...@asandco.co.uk> wrote in message
> > Alan- Hide quoted text -
>
> - Show quoted text -

Hi. This is a very common problem that tends to occur
in MOST programming languages on MOST kinds of computers.
I posted a detailed discussion of why this happens and
what to do about it, in rather greater detail than the
other responses, but it never showed up here.

In short:
-- Floating-point numbers in computers are almost
ALWAYS approximations to the "true" values they should
be.
-- As a result, comparing two floating point numbers
must ALWAYS be done very carefully, because numbers
that "ought" to be exactly equal often differ by some
minute amount.
-- This is also true when comparing one number with
zero, because a number that "ought" to be zero might
actually be some minute number like 0.000000000000147
-- So what to do about it? The suggestion:


> >> Try
> >> if nEval + nDisb >= 0.01

is on the right track. But note, any discrepancy could
just as well be + or - so depending on exactly what
kinds of test you want, you may need to test for a small
negative number too.

-- The better way, also already suggested, is to test
one number for being "very close to zero" or testing two
numbers for being "very close to each other". You decide
upon an "epsilon" value that defined how close is close
enough for your needs, say, epsilon = 0.00000001

Then test for zero like this:
if ( abs( nMyVar ) < epsilon ) THEN it's near zero.
Test two numbers for near-equality like this:
if ( abs( num1 - num2 ) < epsilon ) THEN nearly equal.

My earlier post went into greater detail about WHY
floating point numbers behave this way. I don't know
how many times I have had to present this lecture to
various programmers that I have worked with, but it
doesn't seem to be as common knowledge among programmers
as it ought to be. It is certainly a very common problem.

-- J. J.
-------------------------------------------------

0 new messages