FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour How to compare two values
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
How to compare two values
Posted: Thu Jan 15, 2009 11:36 AM

Sometimes if I compare two decimal point values also if they seem to be the same they have a slightly difference.

I do like this:

if INT(value1 * 1000) - INT(value* 1000) <> 0
endif

But I believe there is a build in function. Does someone know one?
Thanks in advance
Otto

Posts: 4043
Joined: Wed Dec 19, 2007 06:40 PM
Re: How to compare two values
Posted: Thu Jan 15, 2009 12:05 PM

Hello Otto,

I think You have to use the ROUND()-Function for exact results.

Some samples :

SET DECIMALS TO 2
SET FIXED ON

// Function ROUND( nValue, nDec ) => rounded
// nDec = how many Dec.
// Negative = round to 10, 100 ......

ROUND( 10.4, 0 ) => Result : 10.00
ROUND( 10.5, 0 ) => Result : 11.00
ROUND( 10.51, 0 ) => Result : 11.00
ROUND( 10.499999999999, 2 ) => Result 10.50

To round before dec, the argument < nDec > is negative

ROUND(101.99, -1) => Result : 100.00
ROUND(109.99, -1) => Result : 110.00
ROUND(101.99, -2 => Result : 100.00

Regards
Uwe :lol:

Since 1995 ( the first release of FW 1.9 )

i work with FW.

If you have any questions about special functions, maybe i can help.
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: How to compare two values
Posted: Thu Jan 15, 2009 12:20 PM
I compare this way for approximate equality:
#define TOLERANCE 0.0001   // your value


if ABS( n1 - n2 ) < TOLERANCE
   // approximately equal
else
  // not even approx equal
endif
Regards



G. N. Rao.

Hyderabad, India
Posts: 130
Joined: Sat Oct 08, 2005 09:38 PM
Re: How to compare two values
Posted: Thu Jan 15, 2009 03:31 PM

The best way to compare two decimal values:

if ROUND(value1,2) = ROUND(value,2)
endif

Regards,
Birol Betoncu

Birol Betoncu
birol.betoncu@gmail.com
Using Harbour, FWH 19.05, BCC7
Posts: 1048
Joined: Mon Oct 24, 2005 09:54 AM
Re: How to compare two values
Posted: Thu Jan 15, 2009 04:16 PM

I also have problems with INT()!
If I call INT(nParam/aArray[1]) and both params are variables with the same value as decimal-number the result should be 1. But in some cases this brings as result 0! I increase the value from the first param with 0.000001 and all is OK.
Is the number-format from the variables different?? INT-function buggy?

Regards,
Günther
---------------------------------
office@byte-one.com
Posts: 4043
Joined: Wed Dec 19, 2007 06:40 PM
Re: How to compare two values
Posted: Thu Jan 15, 2009 04:26 PM

Hello Günther,

there is nothing wrong with INT().

The function INT() just cuts the decimals ( the values are not rounded ).

var1 := 1.56
var2 := 1.63
var3 := var1 + var2 = 3.19

var4 := INT(var1) + INT(var2) = 2

After the calculation of var1 + var2 => INT(var3) = 3 is OK

If You don't want to use Decimals, You have to use the function ROUND() for exact values.
INT(), I use only for Number-display.
Sample :
I want to show a browser with running numbers inside a listbox.
I start with < nNumber := 1 > than nNumber++ and so on.
The var nNumber is shown in the listbox => 1.00, 2.00 ........
in relation to SET DECIMALS. That is the reason I use INT(nNumber) for display.

Regards
Uwe :lol:

Since 1995 ( the first release of FW 1.9 )

i work with FW.

If you have any questions about special functions, maybe i can help.
Posts: 9022
Joined: Thu Oct 06, 2005 08:17 PM
Re: How to compare two values
Posted: Thu Jan 15, 2009 04:52 PM

I confirm what Uwe said.

EMG

Posts: 1048
Joined: Mon Oct 24, 2005 09:54 AM
Re: How to compare two values
Posted: Fri Jan 16, 2009 12:53 AM
This wrong result of 0 of the following code are only, if one of the values are from an array.
In my actual situation both values in a loop became 0.01.
The result from 0.01/0.01 = 1. And INT(1) should be also 1! But it is 0!
INT(nParam/aArray[1])
Regards,
Günther
---------------------------------
office@byte-one.com
Posts: 9022
Joined: Thu Oct 06, 2005 08:17 PM
Re: How to compare two values
Posted: Fri Jan 16, 2009 08:10 AM

Please post a reduced and self-contained sample of the problem.

EMG

Posts: 300
Joined: Wed Jul 11, 2007 11:06 AM
Re: How to compare two values
Posted: Fri Jan 16, 2009 12:35 PM

I had the same problem in the past and use STRZERO(nVar,10,2) .
I compare strzero of var1 with strzero of var2 .

Posts: 464
Joined: Tue May 16, 2006 07:47 AM
Re: How to compare two values
Posted: Sat Jan 17, 2009 11:04 AM

Hi all

Isn't this essentially just a reflection of the fact that (x)Harbour numeric variables are handled as C double precision floats which means binary representations of floating point numbers and thus the results of (particularly division) operations may not be able to be represented exactly. You can see the problem is equivalent to us using base 10 decimals: Take 10.0000 / 3 and we would get 0.3333. Multiply that by 3 and we would get 0.9999. In other words, seen like this ( 10.000 / 3 ) * 3 = 0.9999 which isn't (exactly) equal to 10.0000. And INT( 0.9999 ) = 0.

Some variance of the tolerance idea should solve the problem. Evaluating the difference between two values as being less than a given tolerance is at least theoretically more robust (and more configurable) than rounding to a given number of decimal places, although the latter method is probably acceptable for most monetary calculations (dollars and cents) where the answer has to come out eventually to two decimal places. That's because depending upon the rounding function either 5.4999999 or 5.50000001 will round differently from 5.5000000 ! Also, although I haven't tested it, I would be pretty sure that testing approximate equality by comparing rounded values would require substantially more CPU clocks.

Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: How to compare two values
Posted: Sat Jan 17, 2009 03:33 PM
betoncu wrote:The best way to compare two decimal values:

if ROUND(value1,2) = ROUND(value,2)
endif

Regards,
Birol Betoncu

This is not the correct logic. Please consider the following numbers.


a := 1.01
b := 1.01499999999999
c := 1.015

Difference between a and b is almost 0.005, where as difference between b and c is near zero.
But the above logic shows a is approx equal to b and b is not even approx equal to c, because a,b and c rouned are 1.01, 1.01 and 1.02.

So, ROUND( a, x ) - ROUND( b, x ) <> 0 also is not the correct logic.

Comparing difference of the two numbers with a tolerance value is the right logic, which can be written in many ways.

Even ROUND( a - b, nDecAccuracy ) == 0 also is another way of writing.

This is the code i use :
x = n1 - n2
return ( x > -epsilon .and. x < epsilon )  // epsilon is my constant value
Regards



G. N. Rao.

Hyderabad, India
Posts: 130
Joined: Sat Oct 08, 2005 09:38 PM
Re: How to compare two values
Posted: Sat Jan 17, 2009 07:00 PM

Yes, you are right.
ROUND( a - b, nDecAccuracy ) == 0 is the best.

Birol:)

Birol Betoncu
birol.betoncu@gmail.com
Using Harbour, FWH 19.05, BCC7
Posts: 130
Joined: Sat Oct 08, 2005 09:38 PM
Re: How to compare two values
Posted: Sat Jan 17, 2009 07:02 PM

Oops, discard my previous message.

Birol Betoncu
birol.betoncu@gmail.com
Using Harbour, FWH 19.05, BCC7

Continue the discussion