Annotation of OpenXM_contrib/gmp/mpfr/mpfr-test.h, Revision 1.1.1.1
1.1 ohara 1: /* auxiliary functions for MPFR tests.
2:
3: Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4:
5: This file is part of the MPFR Library.
6:
7: The MPFR Library is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or (at your
10: option) any later version.
11:
12: The MPFR Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with the MPFR Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #if HAVE_CONFIG_H
23: #include "config.h"
24: #endif
25:
26: #include <math.h>
27: #ifdef __mips
28: #include <sys/fpu.h>
29: #endif
30:
31: /* set precision control to double on x86 */
32: #if (defined (__i386__) || defined (__i486__))
33: #ifdef __CYGWIN32__ /* no fpu_control.h under Cygnus */
34: #define _FPU_EXTENDED 0x300
35: #define _FPU_DOUBLE 0x200
36: #define _FPU_DEFAULT 0x137f
37: #define HAVE_SETFPUCW
38: #else
39: #ifdef HAVE_FPU_CONTROL_H
40: #include <fpu_control.h>
41: #define HAVE_SETFPUCW
42: #endif
43: #endif /* ifdef __CYGWIN32__ */
44: #ifndef __setfpucw
45: #define __setfpucw(cw) __asm__ ("fldcw %0" : : "m" (cw))
46: #endif /* ifndef __setfpucw */
47: #endif /* __i386__ */
48:
49: /* generates a random long int, a random double,
50: and corresponding seed initializing */
51: #ifdef HAVE_LRAND48
52: #define LONG_RAND lrand48
53: #define DBL_RAND drand48
54: #define SEED_RAND srand48
55: #else
56: #define LONG_RAND random
57: #define DBL_RAND() ((double) random() / (double) RAND_MAX)
58: #define SEED_RAND srandom
59: #endif
60:
61: #if defined (__hpux)
62: #define srandom srand48
63: #define random() (mrand48() & 0x7fffffff)
64: #endif
65:
66: void mpfr_test_init _PROTO ((void));
67: double drand _PROTO ((void));
68: int ulp _PROTO ((double, double));
69: double dbl _PROTO ((double, int));
70: double Ulp _PROTO ((double));
71:
72: #define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */
73: #define MAXNORM 1.7976931348623157081e308 /* 2^(1023)*(2-2^(-52)) */
74:
75: /* The MAX, MIN and ABS macros may already be defined if gmp-impl.h has
76: been included. They have the same semantics as in gmp-impl.h, but the
77: expressions may be slightly different. So, it's better to undefine
78: them first, as required by the ISO C standard. */
79: #undef MAX
80: #undef MIN
81: #undef ABS
82: #define MAX(a, b) (((a) > (b)) ? (a) : (b))
83: #define MIN(a, b) (((a) < (b)) ? (a) : (b))
84: #define ABS(x) (((x)>0) ? (x) : -(x))
85:
86: /* initialization function for tests using the hardware floats */
87: void
88: mpfr_test_init ()
89: {
90: #ifdef __mips
91: /* to get denormalized numbers on IRIX64 */
92: union fpc_csr exp;
93:
94: exp.fc_word = get_fpc_csr();
95: exp.fc_struct.flush = 0;
96: set_fpc_csr(exp.fc_word);
97: #endif
98:
99: #ifdef HAVE_SETFPUCW
100: /* sets the precision to double */
101: __setfpucw((_FPU_DEFAULT & (~_FPU_EXTENDED)) | _FPU_DOUBLE);
102: #endif
103: }
104:
105: /* generate a random double using the whole range of possible values,
106: including denormalized numbers, NaN, infinities, ... */
107: double
108: drand (void)
109: {
110: double d; int *i, expo;
111:
112: i = (int*) &d;
113: d = 1.0;
114: if (i[0] == 0)
115: expo = 1; /* little endian, exponent in i[1] */
116: else
117: expo = 0;
118: i[0] = LONG_RAND();
119: i[1] = LONG_RAND();
120: while (i[expo] >= 2146435072)
121: i[expo] = LONG_RAND(); /* avoids NaNs */
122: if ((LONG_RAND() % 2) && !isnan (d))
123: d = -d; /* generates negative numbers */
124: return d;
125: }
126:
127: /* returns ulp(x) for x a 'normal' double-precision number */
128: double
129: Ulp (double x)
130: {
131: double y, eps;
132:
133: if (x < 0) x = -x;
134:
135: y = x * 2.220446049250313080847263336181640625e-16 ; /* x / 2^52 */
136:
137: /* as ulp(x) <= y = x/2^52 < 2*ulp(x),
138: we have x + ulp(x) <= x + y <= x + 2*ulp(x),
139: therefore o(x + y) = x + ulp(x) or x + 2*ulp(x) */
140:
141: eps = x + y;
142: eps = eps - x; /* ulp(x) or 2*ulp(x) */
143:
144: return (eps > y) ? 0.5 * eps : eps;
145: }
146:
147: /* returns the number of ulp's between a and b */
148: int
149: ulp (double a, double b)
150: {
151: if (a==0.0) {
152: if (b==0.0) return 0;
153: else if (b<0.0) return 2147483647;
154: else return -2147483647;
155: }
156: return (a-b)/Ulp(a);
157: }
158:
159: /* return double m*2^e */
160: double
161: dbl (double m, int e)
162: {
163: if (e>=0) while (e-->0) m *= 2.0;
164: else while (e++<0) m /= 2.0;
165: return m;
166: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>