The R Project SVN R

Rev

Rev 44890 | Rev 86145 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
42303 ripley 1
/*
2
 *  Mathlib : A C Library of Special Functions
58977 ripley 3
 *  Copyright (C) 1998-2006 The R Core Team
42303 ripley 4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, a copy is available at
17
 *  http://www.r-project.org/Licenses/
18
 */
19
 
20
#ifdef HAVE_CONFIG_H
21
# include <config.h>
22
# undef fprintf
23
#endif
24
#include "nmath.h"
25
 
26
#ifdef MATHLIB_STANDALONE
27
/*
28
 *  based on code in ../main/arithmetic.c
29
 *  used only in standalone Rmath lib.
30
 */
31
 
32
int R_finite(double x)
33
{
34
#ifdef HAVE_WORKING_ISFINITE
35
    return isfinite(x);
36
# else
37
    return (!isnan(x) & (x != ML_POSINF) & (x != ML_NEGINF));
38
#endif
39
}
40
 
41
/* C++ math header undefines any isnan macro. This file
42
   doesn't get C++ headers and so is safe. */
43
int R_isnancpp(double x)
44
{
42422 ripley 45
    return (isnan(x) != 0);
42303 ripley 46
}
47
 
48
static double myfmod(double x1, double x2)
49
{
50
    double q = x1 / x2;
51
    return x1 - floor(q) * x2;
52
}
53
 
54
double R_pow(double x, double y) /* = x ^ y */
55
{
56
    if(x == 1. || y == 0.)
57
	return(1.);
58
    if(x == 0.) {
59
	if(y > 0.) return(0.);
60
	/* y < 0 */return(ML_POSINF);
61
    }
62
    if (R_FINITE(x) && R_FINITE(y))
63
	return(pow(x,y));
64
    if (ISNAN(x) || ISNAN(y)) {
65
#ifdef IEEE_754
66
	return(x + y);
67
#else
68
	return(ML_NAN);
69
#endif
70
    }
71
    if(!R_FINITE(x)) {
72
	if(x > 0)		/* Inf ^ y */
73
	    return((y < 0.)? 0. : ML_POSINF);
74
	else {			/* (-Inf) ^ y */
75
	    if(R_FINITE(y) && y == floor(y)) /* (-Inf) ^ n */
76
		return((y < 0.) ? 0. : (myfmod(y,2.) ? x  : -x));
77
	}
78
    }
79
    if(!R_FINITE(y)) {
80
	if(x >= 0) {
81
	    if(y > 0)		/* y == +Inf */
82
		return((x >= 1)? ML_POSINF : 0.);
83
	    else		/* y == -Inf */
84
		return((x < 1) ? ML_POSINF : 0.);
85
	}
86
    }
87
    return(ML_NAN);		/* all other cases: (-Inf)^{+-Inf,
88
				   non-int}; (neg)^{+-Inf} */
89
}
90
 
91
double R_pow_di(double x, int n)
92
{
93
    double pow = 1.0;
94
 
95
    if (ISNAN(x)) return x;
96
    if (n != 0) {
97
	if (!R_FINITE(x)) return R_pow(x, (double)n);
98
	if (n < 0) { n = -n; x = 1/x; }
99
	for(;;) {
100
	    if(n & 01) pow *= x;
101
	    if(n >>= 1) x *= x; else break;
102
	}
103
    }
104
    return pow;
105
}
106
 
107
double NA_REAL = ML_NAN;
108
double R_PosInf = ML_POSINF, R_NegInf = ML_NEGINF;
109
 
110
#include <stdio.h>
111
#include <stdarg.h>
44890 ripley 112
void attribute_hidden REprintf(const char *format, ...)
42303 ripley 113
{
114
    va_list(ap);
115
    va_start(ap, format);
116
    fprintf(stderr, format, ap);
117
    va_end(ap);
118
}
119
 
120
#endif /* MATHLIB_STANDALONE */