Canoe
Comprehensive Atmosphere N' Ocean Engine
fcmp.c
Go to the documentation of this file.
1
#include <float.h>
2
#include <math.h>
3
4
/*
5
* Derived from fcmp(), version 1.2.2,
6
* Copyright (c) 1998-2000 Theodore C. Belding
7
* University of Michigan Center for the Study of Complex Systems
8
* <mailto:Ted.Belding@umich.edu>
9
* <http://fcmp.sourceforge.net>
10
*
11
* The major modification we have made is to remove the "epsilon" argument
12
* and set epsilon inside the fcmp() function.
13
*
14
* Description:
15
* It is generally not wise to compare two floating-point values for
16
* exact equality, for example using the C == operator. The function
17
* fcmp() implements Knuth's suggestions for safer floating-point
18
* comparison operators, from:
19
* Knuth, D. E. (1998). The Art of Computer Programming.
20
* Volume 2: Seminumerical Algorithms. 3rd ed. Addison-Wesley.
21
* Section 4.2.2, p. 233. ISBN 0-201-89684-2.
22
*
23
* Input parameters:
24
* x1, x2: numbers to be compared
25
*
26
* This routine may be used for both single and double precision.
27
*
28
* Returns:
29
* -1 if x1 < x2
30
* 0 if x1 == x2
31
* 1 if x1 > x2
32
*/
33
34
int
fcmp
(
double
x1
,
double
x2
) {
35
int
exponent;
36
double
delta, difference;
37
const
double
epsilon = DBL_EPSILON;
38
39
/*
40
* Get exponent(max(fabs(x1),fabs(x2))) and store it in exponent.
41
*
42
* If neither x1 nor x2 is 0,
43
* this is equivalent to max(exponent(x1),exponent(x2)).
44
*
45
* If either x1 or x2 is 0, its exponent returned by frexp would be 0,
46
* which is much larger than the exponents of numbers close to 0 in
47
* magnitude. But the exponent of 0 should be less than any number
48
* whose magnitude is greater than 0.
49
*
50
* So we only want to set exponent to 0 if both x1 and x2 are 0.
51
* Hence, the following works for all x1 and x2.
52
*/
53
frexp(fabs(
x1
) > fabs(
x2
) ?
x1
:
x2
, &exponent);
54
55
/*
56
* Do the comparison.
57
*
58
* delta = epsilon*pow(2,exponent)
59
*
60
* Form a neighborhood around x2 of size delta in either direction.
61
* If x1 is within this delta neighborhood of x2, x1 == x2.
62
* Otherwise x1 > x2 or x1 < x2, depending on which side of
63
* the neighborhood x1 is on.
64
*/
65
delta = ldexp(epsilon, exponent);
66
difference =
x1
-
x2
;
67
68
if
(difference > delta) {
69
/* x1 > x2 */
70
return
1;
71
}
else
if
(difference < -delta) {
72
/* x1 < x2 */
73
return
-1;
74
}
else
{
75
/* -delta <= difference <= delta */
76
return
0;
/* x1 == x2 */
77
}
78
}
fcmp
int fcmp(double x1, double x2)
Definition:
fcmp.c:34
make_plots.x1
int x1
Definition:
make_plots.py:10
make_plots.x2
int x2
Definition:
make_plots.py:11
src
climath
fcmp.c
Generated by
1.9.1