aboutsummaryrefslogtreecommitdiff
path: root/src/jtutil/miscfp.cc
blob: 7b151c1de724972359886d7dfb6f99e4fad8943c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// miscfp.cc -- misc floating-point functions

//
// signum - sign of a floating point number
// hypot3 - 3D Euclidean distance
// arctan_xy - 4-quadrant arc tangent
// modulo_reduce - reduce an angle modulo 2*pi radians (360 degrees)
//

#include <math.h>
#include "stdc.h"
#include "util.hh"

//******************************************************************************

//
// This function computes the floating point "signum" function (as in APL),
// signum(x) = -1.0, 0.0, or +1.0, according to the sign of x.
//
namespace jtutil
	  {
double signum(double x)
{
if (x == 0.0)
   then return 0.0;
   else return (x > 0.0) ? 1.0 : -1.0;
}
	  };

//******************************************************************************

//
// This function computes the 3-dimensional Euclidean distance,
// analogously to the standard math library function  hypot(2) .
//
// Arguments:
// (x,y,z) = (in) The rectangular coordinates of a point in $\Re^3$.
//
// Result:
// The function returns the Euclidean distance of (x,y,z) from the origin.
//
// Bugs:
// Unlike  hypot(2), this function takes no special care to avoid
// unwarranted IEEE exceptions if any of |x|, |y|, or |z| is close to
// the overflow and/or underflow threshold.
//
namespace jtutil
	  {
double hypot3(double x, double y, double z)
{
return std::sqrt(x*x + y*y + z*z);
}
	  };

//******************************************************************************

//
// This function computes a four-quadrant arctangent, using what I think
// is the "right" ordering of the arguments, and returning 0.0 if both
// arguments are 0.0.
//
// Arguments:
// (x,y) = (in) The rectangular coordinates of a point in $\Re^2$.
//
// Result:
// The function returns a value $\theta$ such that $x + iy = R e^{i\theta}$ for
// some real $R$, i.e. it returns the angle between the positive $x$ axis and
// the line joining the origin and the point $(x,y)$.
//
namespace jtutil
	  {
double arctan_xy(double x, double y)
{
return ((x == 0.0) && (y == 0.0))
       ?
       : std::atan2(y, x);	// note reversed argument order (y,x)!!
}
	  };

//******************************************************************************

//
// This function reduces  x  modulo  xmod  to be (fuzzily) in the range
//  [xmin, xmax] , or does an  error_exit()  if no such value exists.
//
namespace jtutil
	  {
double modulo_reduce(double x, double xmod, double xmin, double xmax)
{
double xx = x;

	while (fuzzy<double>::LT(xx, xmin))
	{
	xx += xmod;
	}

	while (fuzzy<double>::GT(xx, xmax))
	{
	xx -= xmod;
	}

if (! (fuzzy<double>::GE(xx, xmin) && fuzzy<double>::LE(xx, xmax)) )
   then jtutil::error_exit(ERROR_EXIT,
"***** modulo_reduce(): no modulo value is fuzzily within specified range!\n"
"                       x = %g   xmod = %g\n"
"                       [xmin,xmax] = [%g,%g]\n"
"                       ==> xx = %g\n"
,
			   x, xmod,
			   xmin, xmax,
			   xx);					/*NOTREACHED*/

return xx;
}
	  }