/[ascend]/trunk/base/generic/compiler/rounded.c
ViewVC logotype

Contents of /trunk/base/generic/compiler/rounded.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 515 - (show annotations) (download) (as text)
Thu Apr 20 00:24:34 2006 UTC (18 years, 2 months ago) by ben.allan
File MIME type: text/x-csrc
File size: 7793 byte(s)
commented an endif.
1 /*
2 * Rounded arithmetic routines
3 * by Tom Epperly
4 * Version: $Revision: 1.6 $
5 * Version control file: $RCSfile: rounded.c,v $
6 * Date last modified: $Date: 1997/07/21 16:56:47 $
7 * Last modified by: $Author: kt2g $
8 * 2/28/89
9 *
10 * This file is part of the Ascend Language Interpreter.
11 *
12 * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
13 *
14 * The Ascend Language Interpreter is free software; you can redistribute
15 * it and/or modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * The Ascend Language Interpreter is distributed in hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING.
28 *
29 */
30
31 #include <stdarg.h>
32 #include <utilities/ascConfig.h>
33 #include "compiler.h"
34 #include <utilities/ascPanic.h>
35 #include "rounded.h"
36 #define IsOdd(i) ((i & 1)!=0)
37
38 #ifndef lint
39 static CONST char RoundedRCSid[] = "$Id: rounded.c,v 1.6 1997/07/21 16:56:47 kt2g Exp $";
40 #endif
41
42 #ifndef SLOPPY
43
44 #ifdef mips
45 #include <mips/fpu.h>
46
47 union fpc_csr global_fpc_csr , global_temp_fpc_csr;
48
49 #define CHANGEROUNDINGMODE(x) global_fpc_csr.fc_word = get_fpc_csr(); \
50 global_temp_fpc_csr.fc_word = global_fpc_csr.fc_word;\
51 global_temp_fpc_csr.fc_struct.rounding_mode = x;\
52 set_fpc_csr(global_temp_fpc_csr.fc_word)
53 #define RESETROUNDINGMODE set_fpc_csr(global_fpc_csr)
54
55 #else
56
57 #include <ieeefp.h>
58
59 fp_rnd global_rnd_mode;
60
61 #define CHANGEROUNDINGMODE(x) global_rnd_mode = fpgetround();\
62 fpsetround(x)
63 #define RESETROUNDINGMODE fpsetround(global_rnd_mode)
64 #define ROUND_TO_MINUS_INFINITY FP_RM
65 #define ROUND_TO_PLUS_INFINITY FP_RP
66
67 #endif /* mips */
68
69 double DPlus(register double d1, register double d2)
70 {
71 register double result;
72 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
73 result = d1+d2;
74 RESETROUNDINGMODE;
75 return result;
76 }
77
78 double UPlus(register double d1, register double d2)
79 {
80 register double result;
81 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
82 result = d1+d2;
83 RESETROUNDINGMODE;
84 return result;
85 }
86
87 double DMinus(register double d1, register double d2)
88 {
89 register double result;
90 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
91 result = d1-d2;
92 RESETROUNDINGMODE;
93 return result;
94 }
95
96 double UMinus(register double d1, register double d2)
97 {
98 register double result;
99 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
100 result = d1-d2;
101 RESETROUNDINGMODE;
102 return result;
103 }
104
105 double DPow(register double d1, register double d2)
106 {
107 register double result;
108 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
109 result = pow(d1,d2);
110 RESETROUNDINGMODE;
111 return result;
112 }
113
114 double UPow(register double d1, register double d2)
115 {
116 register double result;
117 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
118 result = pow(d1,d2);
119 RESETROUNDINGMODE;
120 return result;
121 }
122
123 double DTimes(register double d1, register double d2)
124 {
125 register double result;
126 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
127 result = d1*d2;
128 RESETROUNDINGMODE;
129 return result;
130 }
131
132 double UTimes(register double d1, register double d2)
133 {
134 register double result;
135 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
136 result = d1*d2;
137 RESETROUNDINGMODE;
138 return result;
139 }
140
141 double DDivide(register double d1, register double d2)
142 {
143 register double result;
144 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
145 result = d1/d2;
146 RESETROUNDINGMODE;
147 return result;
148 }
149
150 double UDivide(register double d1, register double d2)
151 {
152 register double result;
153 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
154 result = d1/d2;
155 RESETROUNDINGMODE;
156 return result;
157 }
158
159 double DSqr(register double d)
160 {
161 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
162 d *= d;
163 RESETROUNDINGMODE;
164 return d;
165 }
166
167 double USqr(register double d)
168 {
169 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
170 d *= d;
171 RESETROUNDINGMODE;
172 return d;
173 }
174
175 double DSqrt(register double d)
176 {
177 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
178 d = sqrt(d);
179 RESETROUNDINGMODE;
180 return d;
181 }
182
183 double USqrt(register double d)
184 {
185 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
186 d = sqrt(d);
187 RESETROUNDINGMODE;
188 return d;
189 }
190
191 double DExp(register double d)
192 {
193 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
194 d = exp(d);
195 RESETROUNDINGMODE;
196 return d;
197 }
198
199 double UExp(register double d)
200 {
201 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
202 d = exp(d);
203 RESETROUNDINGMODE;
204 return d;
205 }
206
207 double DLog(register double d)
208 {
209 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
210 d = log10(d);
211 RESETROUNDINGMODE;
212 return d;
213 }
214
215 double ULog(register double d)
216 {
217 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
218 d = log10(d);
219 RESETROUNDINGMODE;
220 return d;
221 }
222
223 #ifdef HAVE_ERF
224 double DErf(register double d)
225 {
226 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
227 d = erf(d);
228 RESETROUNDINGMODE;
229 return d;
230 }
231
232 double UErf(register double d)
233 {
234 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
235 d = erf(d);
236 RESETROUNDINGMODE;
237 return d;
238 }
239 #endif /* HAVE_ERF */
240
241 double DLn(register double d)
242 {
243 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
244 d = log(d);
245 RESETROUNDINGMODE;
246 return d;
247 }
248
249 double ULn(register double d)
250 {
251 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
252 d = log(d);
253 RESETROUNDINGMODE;
254 return d;
255 }
256
257 double DIPow(register double d, long int n)
258 {
259 register double result;
260 int negative;
261 if (n==0) return 1.0;
262 if ((n<0)&&(d==0.0)) {
263 Asc_Panic(2, NULL, "Zero raised to a zero power.\n");
264 }
265 if (d==0.0) return 0.0;
266 negative = (d<0.0) &&(IsOdd(n));
267 d = fabs(d);
268 result = 1.0;
269 if (negative) { CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY); }
270 else { CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY); }
271 if (n < 0)
272 while(n++<0) result /= d;
273 else
274 while(n-->0) result *= d;
275 RESETROUNDINGMODE;
276 assert(result==result);
277 return (negative) ? -result : result ;
278 }
279
280 double UIPow(register double d, long int n)
281 {
282 register double result;
283 int negative;
284 if (n==0) return 1.0;
285 if ((n<0)&&(d==0.0)) {
286 Asc_Panic(2, NULL,
287 "Zero raised to a zero power.\n");
288 }
289 if (d==0.0) return 0.0;
290 negative = (d<0.0) && (IsOdd(n));
291 d = fabs(d);
292 result = 1.0;
293 if (negative) { CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY); }
294 else { CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY); }
295 if (n < 0)
296 while(n++<0) result /= d;
297 else
298 while(n-->0) result *= d;
299 RESETROUNDINGMODE;
300 assert(result==result);
301 return (negative) ? -result : result;
302 }
303
304 double Dltod(long int l)
305 {
306 register double result;
307 CHANGEROUNDINGMODE(ROUND_TO_MINUS_INFINITY);
308 result = (double)l;
309 RESETROUNDINGMODE;
310 return result;
311 }
312
313 double Ultod(long int l)
314 {
315 register double result;
316 CHANGEROUNDINGMODE(ROUND_TO_PLUS_INFINITY);
317 result = (double)l;
318 RESETROUNDINGMODE;
319 return result;
320 }
321
322 #else
323 double DIPow(register double d, long n)
324 {
325 register double result;
326 if (n==0) return 1.0;
327 if ((n<0)&&(d==0.0)) {
328 Asc_Panic(2, NULL, "Zero raised to a zero power.\n");
329 }
330 if (d==0.0) return 0.0;
331 result = 1.0;
332 if (n < 0)
333 while(n++<0) result /= d;
334 else
335 while(n-->0) result *= d;
336 assert(result==result);
337 return result;
338 }
339
340 double UIPow(register double d, long n)
341 {
342 register double result;
343 if (n==0) return 1.0;
344 if ((n<0)&&(d==0.0)) {
345 Asc_Panic(2, NULL, "Zero raised to a zero power.\n");
346 }
347 if (d==0.0) {
348 return 0.0;
349 }
350 result = 1.0;
351 if (n < 0) {
352 while(n++<0) result /= d;
353 } else {
354 while(n-->0) result *= d;
355 }
356 assert(result==result);
357 return result;
358 }
359
360 #endif /* SLOPPY */

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22