Annotation of OpenXM_contrib/gmp/mpfr/mpfr-test.h, Revision 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>