Board index » delphi » Help Comparing Real numbers!!! Porting TPW to Delphi

Help Comparing Real numbers!!! Porting TPW to Delphi

In the process of porting several programs from tpw 1.5 to D1, I am failing
on a comparision of what appear to be equal real numbers.

value : Real;
value := 1.16;

if value = 1.16 then
 begin

Fails every time.  Whole numbers compare properly.  Anything with a decimal
fraction declared as a literal in the IF statement fails.

Lost two days with the de{*word*81} etc. trapping a zero divide error because a
compare failed to put the proper value in for the divisor.  Using the
Evaluate/Modify debuffing window the correct value is being compared to the
literal - but it fails every time.  

BTW works fine in TPW!  In the immortal words of Rickey Ricardo - " 'SPLAIN
LUCY"!

 

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


Its never a good idea to test a Real for equality with another real. The
value 1.16 is actually stored in a real as 1.15999999999985 or some such.
(try r := 1.16; label1.caption := Format ('%g', [r]);)

Quote
Bill Delmore wrote in message

<01be5548$93c7be60$7568e...@iteq.mnsinc.com>...
Quote
>In the process of porting several programs from tpw 1.5 to D1, I am failing
>on a comparision of what appear to be equal real numbers.

>value : Real;
>value := 1.16;

>if value = 1.16 then
> begin

>Fails every time.  Whole numbers compare properly.  Anything with a decimal
>fraction declared as a literal in the IF statement fails.

>Lost two days with the de{*word*81} etc. trapping a zero divide error because a
>compare failed to put the proper value in for the divisor.  Using the
>Evaluate/Modify debuffing window the correct value is being compared to the
>literal - but it fails every time.

>BTW works fine in TPW!  In the immortal words of Rickey Ricardo - " 'SPLAIN
>LUCY"!

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


I did a quick test and got the same results. That's crazy. Why have an
equality operator for a given type if it doesn't work?!? It also breaks in
the same way for the Single and Double types, but works properly for the
Extended type. In the future, I'll be using Extended for all my floating
point needs.

Eric.

Quote
Bill Delmore wrote in message

<01be5548$93c7be60$7568e...@iteq.mnsinc.com>...
Quote
>In the process of porting several programs from tpw 1.5 to D1, I am failing
>on a comparision of what appear to be equal real numbers.

>value : Real;
>value := 1.16;

>if value = 1.16 then
> begin

>Fails every time.  Whole numbers compare properly.  Anything with a decimal
>fraction declared as a literal in the IF statement fails.

>Lost two days with the de{*word*81} etc. trapping a zero divide error because a
>compare failed to put the proper value in for the divisor.  Using the
>Evaluate/Modify debuffing window the correct value is being compared to the
>literal - but it fails every time.

>BTW works fine in TPW!  In the immortal words of Rickey Ricardo - " 'SPLAIN
>LUCY"!

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


I have given up trying to compare real numbers in EVERY programming
language.
I either multiply it to an integer then test it or convert it to an
exact string then test it. I have written a couple of convert to string
functions for this purpose. If you want them e-mail me.(Tiny & simple
but Work well)
Nick
Quote
Bill Delmore wrote:

> In the process of porting several programs from tpw 1.5 to D1, I am failing
> on a comparision of what appear to be equal real numbers.

> value : Real;
> value := 1.16;

> if value = 1.16 then
>  begin

> Fails every time.  Whole numbers compare properly.  Anything with a decimal
> fraction declared as a literal in the IF statement fails.

> Lost two days with the de{*word*81} etc. trapping a zero divide error because a
> compare failed to put the proper value in for the divisor.  Using the
> Evaluate/Modify debuffing window the correct value is being compared to the
> literal - but it fails every time.

> BTW works fine in TPW!  In the immortal words of Rickey Ricardo - " 'SPLAIN
> LUCY"!

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


Quote
Bill Delmore wrote:

> In the process of porting several programs from tpw 1.5 to D1, I am failing
> on a comparision of what appear to be equal real numbers.

> value : Real;
> value := 1.16;

> if value = 1.16 then
>  begin

> Fails every time.  Whole numbers compare properly.  Anything with a decimal
> fraction declared as a literal in the IF statement fails.

I cannot imagine how this could have ever worked with TPW 1.5!
Real numbers are, what the word says, real. And because nature
has no edges, real numbers cannot be compared for equaltiy.
only for similarity. There are various methods to do that,
like "divide them and compare with 1.0000 +- delta" or
"subtract them, make Abs and compare with a value derived
from the average" (div/0 secure), or "add and sub delta to
one value, then check for in-between" etc.

Franz Glaser

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


On 10 Feb 1999 22:56:09 GMT, "Bill Delmore" <bdelm...@iteq.com> wrote:

Quote
>In the process of porting several programs from tpw 1.5 to D1, I am failing
>on a comparision of what appear to be equal real numbers.

>value : Real;
>value := 1.16;

>if value = 1.16 then
> begin

>Fails every time.  Whole numbers compare properly.  Anything with a decimal
>fraction declared as a literal in the IF statement fails.

See D. E. Knuth, The Art of Computer Programming, Vol 2: Seminumerical
Algorithms. While you're at it, take a look at The Elements of
Programming Style, by Brian Kernighan and P. J. Plauger.

You were just lucky that it worked in TPW. It uses a different
representation for floating point numbers, but one that is no more
accurate or precise than Delphi's native format. You just got lucky that
the specific values you used happened to work the way you expected.

Never compare floating point numbers for equality.

--
Ray Lischner  (http://www.bardware.com)
co-author (with John Doyle) of Shakespeare for Dummies

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


In article <36C22B2A.A9183...@eunet.at>, meg-gla...@eunet.at says...

Quote

>Bill Delmore wrote:

>> In the process of porting several programs from tpw 1.5 to D1, I am failing
>> on a comparision of what appear to be equal real numbers.

>> value : Real;
>> value := 1.16;

>> if value = 1.16 then
>>  begin

>> Fails every time.  Whole numbers compare properly.  Anything with a decimal
>> fraction declared as a literal in the IF statement fails.

>I cannot imagine how this could have ever worked with TPW 1.5!

The reason this works in tpw 1.5 but not delphi is that the 1.16 is stored
extended in Delphi but Real in TPW.  Just make value extended.

Quote
>Real numbers are, what the word says, real. And because nature
>has no edges, real numbers cannot be compared for equaltiy.
>only for similarity.

I don't agree with this exactly.  Reals ofen can be validly compared equal, for
example consider the code

Property test : real read fValue write SetTest;

  Procedure SetTest(Value: Real);
Begin
  if (Value) = fValue)) Then Exit;
  fValue = Value;
  // recompute the component  
End;

test := 1.6;  // may or may not recompute the component.
test := 1.6;  // will not recompute the component

Perfectly valid use of = for real numbers.

Second, as you know, the real data type is not the mathematical real number.
The problem is that the real data type has edges and the real number doesn't.  
The the associtive propery of reals doesn't hold for real data types.  I'm just
an annoying nitpicker.  

Quote
> There are various methods to do that,
>like "divide them and compare with 1.0000 +- delta" or
>"subtract them, make Abs and compare with a value derived
>from the average" (div/0 secure), or "add and sub delta to
>one value, then check for in-between" etc

I DO agree completely if you compute a real number in two different ways, e.g,
(34.7*value)/17.123 you might not get 37.7*(Value/17.123), and you have to use
the delta method, and then I agree with your excellent comments.

-John_Mer...@Brown.EDU

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


Quote
John_Mertus wrote:

> >Real numbers are, what the word says, real. And because nature
> >has no edges, real numbers cannot be compared for equaltiy.
> >only for similarity.

> I don't agree with this exactly.  Reals ofen can be validly compared equal, for
> example consider the code
... snip
> Second, as you know, the real data type is not the mathematical real number.
> The problem is that the real data type has edges and the real number doesn't.
> The the associtive propery of reals doesn't hold for real data types.  I'm just
> an annoying nitpicker.

I found out that there MUST be a difference between
mathematicians like you (I often name them "egg heads")
and people who deal with measurement and instrumentation,
like me.

I learned calculating with a wooden ruler (I hope it is
the correct vocable, the one with the logarithmic scale)
and I learned reading values from instruments with a
pointer like voltmeters. This might be the background of
what I name "real" world or - nature.

Accuracy is a matter of _definition_ there. And REAL type
values are such a matter, regardless of their resulution,
say "where the edges occur". It is impossible to store the
value 0.1 in a real variable if it is a binary one, regard-
less of the size of the mantissa, how _extended_ ever.
This is the same as 1/3 in decimal.

:-) Franz Glaser

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


Thank You to everyone who responded.  Maybe Inprise should include a
compiler option to generate a warning on real number comparisons that
employ literals as one of the arguments.  I changed the code to compare
above and below the targeted value.  Fortunately there are only about 15 of
these specific values.

I have a larger compute bound program loaded with reals and literal
comparisons. Looks like its going to be fun :(

I wrote the original in TP 3.0 ported to TPW and now to Delphi.  This
explains the mystery of why tpw and TP worked and D does not.    Wish I had
understood the limits of reals 10 years ago - would have left all the data
as strings - used reals to speed up my fine 8086 XT to avoide all of the
conversions and outsmarted myself.

Bill Delmore <bdelm...@iteq.com> wrote in article
<01be5548$93c7be60$7568e...@iteq.mnsinc.com>...

Quote
> In the process of porting several programs from tpw 1.5 to D1, I am
failing
> on a comparision of what appear to be equal real numbers.

> value : Real;
> value := 1.16;

> if value = 1.16 then
>  begin

> Fails every time.  Whole numbers compare properly.  Anything with a
decimal
> fraction declared as a literal in the IF statement fails.

> Lost two days with the de{*word*81} etc. trapping a zero divide error because
a
> compare failed to put the proper value in for the divisor.  Using the
> Evaluate/Modify debuffing window the correct value is being compared to
the
> literal - but it fails every time.  

> BTW works fine in TPW!  In the immortal words of Rickey Ricardo - "
'SPLAIN
> LUCY"!

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


Quote
Eric Anderson wrote:
> I did a quick test and got the same results. That's crazy. Why have an
> equality operator for a given type if it doesn't work?!? It also breaks in
> the same way for the Single and Double types, but works properly for the
> Extended type.

See there you've posted the answer and didn't even know it.  All constants are
saved as extended by default.  Consequently, due to the various
precision/rounding issues that others have already posted any conversion through
another floating point type will likely result in a mismatch.  If you're still
not buying it, consider that floating point represents the set of all real
numbers.  Any given real number is infinitely 'narrow'.  Thus equality is not
physically possible as there would always be finite mismatch between two
physical quantities.  Of course in a computer the individual values are not
infinitely narrow.  Thus, sometimes you can get lucky.  You should never count
on this, though as It will definitely come back and bite you.

Quote
> In the future, I'll be using Extended for all my floating
> point needs.

This won't save you.  If one value is the result of an expression then all bets
are off.  Besides, extended sucks for a lot of reasons.   Use a tolerance range
to check for equality.

Bob Lee

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


Quote
> I cannot imagine how this could have ever worked with TPW 1.5!
> Real numbers are, what the word says, real. And because nature
> has no edges, real numbers cannot be compared for equaltiy.
> only for similarity. There are various methods to do that,
> like "divide them and compare with 1.0000 +- delta" or
> "subtract them, make Abs and compare with a value derived
> from the average" (div/0 secure), or "add and sub delta to
> one value, then check for in-between" etc.

> Franz Glaser

Would

If Abs(Real1-Real2)<0.0000001

work?

--
|? Algirdas 'Ze{*word*104}' Kepezinskas
|? E-Mail: cy...@vil.ktu.lt
|? ICQ 14187537
|? URL: http://www.botepidemic.com/fmods
+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*++*+*+*+*
|? If time is killing you
|?????????????????? kill some for time..
?

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


Quote
Algirdas Kepezinskas wrote in message <36C2FA34.33B1E...@vil.ktu.lt>...
>> I cannot imagine how this could have ever worked with TPW 1.5!
>If Abs(Real1-Real2)<0.0000001

>work?

You need a "rule" appropriate for the problem you're trying to solve.
Usually, you need to decide whether the "rule" is for an absolute
error comparison, or a relative error comparison.

Take a look at Item B-11 at
www.efg2.com/lab/library/delphi/MathInfo

efg
_________________________________
efg's Computer Lab:       www.efg2.com/lab
Delphi Books:  www.efg2.com/lab/TechBooks/Delphi.htm

Earl F. Glynn     E-Mail:  EarlGl...@att.net
Overland Park, KS  USA

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


In article <01be5548$93c7be60$7568e...@iteq.mnsinc.com>,
  "Bill Delmore" <bdelm...@iteq.com> wrote:

Quote
> In the process of porting several programs from tpw 1.5 to D1, I am failing
> on a comparision of what appear to be equal real numbers.

> value : Real;
> value := 1.16;

> if value = 1.16 then
>  begin

> Fails every time.  Whole numbers compare properly.  Anything with a decimal
> fraction declared as a literal in the IF statement fails.

> Lost two days with the de{*word*81} etc. trapping a zero divide error because a
> compare failed to put the proper value in for the divisor.  Using the
> Evaluate/Modify debuffing window the correct value is being compared to the
> literal - but it fails every time.

> BTW works fine in TPW!  In the immortal words of Rickey Ricardo - " 'SPLAIN
> LUCY"!

When using floating point comparisons you should NEVER EVER use the equality
operator to compare two values, unless you can be sure they are actually an
integer value - but then you would use an integer!  Even if it works in the
extended type there is no guarantee it will work for another value.  Compare
the difference between the two to a small number or use a < or > comparison
if you can.

Trevor Hand

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


In article <36C2B67B.1D03B...@eunet.at>, meg-gla...@eunet.at says...

Quote

>John_Mertus wrote:

>> >Real numbers are, what the word says, real. And because nature
>> >has no edges, real numbers cannot be compared for equaltiy.
>> >only for similarity.

>> I don't agree with this exactly.  Reals ofen can be validly compared equal,
for
>> example consider the code
>... snip
>> Second, as you know, the real data type is not the mathematical real number.
>> The problem is that the real data type has edges and the real number
doesn't.
>> The the associtive propery of reals doesn't hold for real data types.  I'm
just
>> an annoying nitpicker.

>I found out that there MUST be a difference between
>mathematicians like you (I often name them "egg heads")
>and people who deal with measurement and instrumentation,
>like me.

Wow flamed for saying someone was correct.  Most people call me stupid, not an
egg head:)  I only pointed out that there are also *VALID* reasons for doing =
on the data type real, extended, et. al.  And the example I gave is a valid
reason. One doesn't always have to avoid = on reals.

Quote

>Accuracy is a matter of _definition_ there. And REAL type
>values are such a matter, regardless of their resulution,
>say "where the edges occur". It is impossible to store the
>value 0.1 in a real variable if it is a binary one, regard-
>less of the size of the mantissa, how _extended_ ever.
>This is the same as 1/3 in decimal.

Of course, as I said before  I agree completely with you.  Please reread the
post, I even said you comments were excellent.  I just disagree with that one
should never use =.  And the example was one I use ALL the time.

BTW, my first computer program was on an analog computer in the ba{*word*224}t of the
E.E. building at Carnegie Mellon.  How about a computer that can multiply,
divide, integrate but NOT add or subtract.  

-John_Mer...@Brown.EDU

Re:Help Comparing Real numbers!!! Porting TPW to Delphi


So, something like this might be better:

const
    Tol: Extended = 1e-5;

function AreReallyClose(A,B: Extended): Boolean;
begin
    Result := Abs(A-B) <= Tol
end;

I'm assuming that Delphi's other floating point types will be correctly
converted to an Extended through the parameter passing. Probably not 100%
safe.

Eric.

Go to page: [1] [2]

Other Threads