1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % File:         PB:FLOAT.C
5 % Description:  Miscellaneous floating point support routines.
6 % Author:       Leigh Stoller
7 % Created:      29-Oct-86
8 % Modified:
9 % Mode:         Text
10 % Package:
11 % Status:       Open Source: BSD License
12 %
13 %
14 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15 %
16 % (c) Copyright 1983, Hewlett-Packard Company, see the file
17 %            HP_disclaimer at the root of the PSL file tree
18 %
19 %
20 % (c) Copyright 1982, University of Utah
21 %
22 % Redistribution and use in source and binary forms, with or without
23 % modification, are permitted provided that the following conditions are met:
24 %
25 %    * Redistributions of source code must retain the relevant copyright
26 %      notice, this list of conditions and the following disclaimer.
27 %
28 %    * Redistributions in binary form must reproduce the above copyright
29 %      notice, this list of conditions and the following disclaimer in the
30 %      documentation and/or other materials provided with the distribution.
31 %
32 % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
34 % THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
35 % PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR
36 % CONTRIBUTORS
37 % BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 % POSSIBILITY OF SUCH DAMAGE.
44 %
45 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 %
47 %
48 %
49 % Revisions:
50 %
51 % 05-May-87 (Leigh Stoller)
52 %  Added C defintions for external float routines used in fast-math.sl.
53 %
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55 */
56 
57 
58 #include <string.h>
59 #include <math.h>
60 #include <stdio.h>
61 #include <float.h>
62 
63 
64 #define PROTECT_FP_CALL(stmt)  {		\
65   unsigned int cw; \
66   _clearfp();  \
67    cw = _controlfp(~0, _MCW_EM); /* Restore default error handling */ 	\
68   stmt; \
69   _controlfp(cw, _MCW_EM);  /* Restore previous state */ 	\
70 }
71 
72 
73 /* Tag( uxfloat )
74  */
uxfloat(f,i)75 uxfloat(f,i)
76      double *f;
77      int i;
78 {
79   *f = i;
80 }
81 
82 /* Tag( uxfix )
83  */
uxfix(f)84 int uxfix(f)
85      double *f;
86 {
87   return (int)*f;
88 }
89 
90 /* Tag( uxassign )
91  */
uxassign(f1,f2)92 uxassign(f1,f2)
93      double *f1, *f2;
94 {
95   *f1 = *f2;
96 }
97 
98 /* Tag( uxplus2 )
99  */
uxplus2(f1,f2,f3)100 uxplus2(f1,f2,f3)
101      double *f1, *f2, *f3;
102 {
103   *f1 = *f2 + *f3;
104 }
105 
106 /* Tag( uxdifference )
107  */
uxdifference(f1,f2,f3)108 uxdifference(f1,f2,f3)
109      double *f1, *f2, *f3;
110 {
111   *f1 = *f2 - *f3;
112 }
113 
114 /* Tag( uxtimes2 )
115  */
uxtimes2(f1,f2,f3)116 uxtimes2(f1,f2,f3)
117      double *f1, *f2, *f3;
118 {
119   *f1 = *f2 * *f3;
120 }
121 
122 /* Tag( uxquotient )
123  */
uxquotient(f1,f2,f3)124 uxquotient(f1,f2,f3)
125      double *f1, *f2, *f3;
126 {
127   *f1 = *f2 / *f3;
128 }
129 
130 /* Tag( uxgreaterp )
131  */
uxgreaterp(f1,f2,val1,val2)132 int uxgreaterp(f1,f2,val1,val2)
133      double *f1, *f2;
134      int val1, val2;
135 {
136   if (*f1 > *f2)
137     return val1;
138   else
139     return val2;
140 }
141 
142 /* Tag( uxlessp )
143  */
uxlessp(f1,f2,val1,val2)144 int uxlessp(f1,f2,val1,val2)
145      double *f1, *f2;
146      int val1, val2;
147 {
148   if (*f1 < *f2)
149     return val1;
150   else
151     return val2;
152 }
153 
154 /* Tag( uxwritefloat )
155  */
uxwritefloat(buf,flt,convstr)156 uxwritefloat(buf, flt, convstr)
157      char *buf;          /* String buffer to return float int */
158      double *flt;        /* Pointer to the float */
159      char *convstr;      /* String containing conversion field for sprintf */
160 {
161   char *temps, *dot, *e;
162   char tempbuf[100]; /* reasonable size limit */
163   //  double tempf;
164 
165   temps = buf + 4;       /* Skip over lisp string length to write data */
166 
167   _snprintf(temps, 95, convstr, *flt);
168 
169   if (_finite(*flt))
170     {
171     /* Make sure that there is a trailing .0
172      */
173     dot = strrchr(temps, '.');
174     if (dot == NULL)
175       /* Check to see if the number is in scientific notation. If so, we need
176        *  add the .0 into the middle of the string, just before the e.
177        */
178       if ((e = strrchr(temps, 'e')) || (e = strrchr(temps, 'E')))
179 	{
180 	  strcpy(tempbuf, e);       /* save save exponent part */
181 	  *e = '\0';
182 	  strcat(temps, ".0");     /* Add .0 ono original string */
183 	  strcat(temps, tempbuf);  /* add the exponent part onto the end */
184 	}
185       else
186 	{
187 	  strcat(temps, ".0");
188 	}
189     }
190   /* Install the length of the string into the Lisp header word
191    */
192   *((int *)buf) = strlen(temps) - 1;
193 }
194 
195 
196 /* Tag( uxdoubletofloat )
197  */
uuxdoubletofloat(dbl,flt)198 uuxdoubletofloat (dbl,flt)
199      double *dbl;
200      float  *flt;
201 {
202   *flt = (float) *dbl;
203 }
204 
uuxfloattodouble(flt,dbl)205 uuxfloattodouble (flt,dbl)
206      float  *flt;
207      double *dbl;
208 {
209   *dbl = (double) *flt;
210 }
211 
212 /* Functions for fast-math.sl (Unix C replacement for mathlib.) */
uuxsin(r,x)213 uuxsin (r, x)
214      double *r, *x;
215 {
216   PROTECT_FP_CALL(*r = sin( *x ) )
217 }
218 
uuxcos(r,x)219 uuxcos (r, x)
220      double *r, *x;
221 {
222   PROTECT_FP_CALL(*r = cos( *x ))
223 }
224 
uuxtan(r,x)225 uuxtan (r, x)
226      double *r, *x;
227 {
228   PROTECT_FP_CALL(*r = tan( *x ))
229 }
230 
uuxasin(r,x)231 uuxasin (r, x)
232      double *r, *x;
233 {
234   PROTECT_FP_CALL(*r = asin( *x ))
235 }
236 
uuxacos(r,x)237 uuxacos (r, x)
238      double *r, *x;
239 {
240   PROTECT_FP_CALL(*r = acos( *x ))
241 }
242 
uuxatan(r,x)243 uuxatan (r, x)
244      double *r, *x;
245 {
246   PROTECT_FP_CALL(*r = atan( *x ))
247 }
248 
uuxsqrt(r,x)249 uuxsqrt (r, x)
250      double *r, *x;
251 {
252   PROTECT_FP_CALL(*r = sqrt( *x ))
253 }
254 
uuxexp(r,x)255 uuxexp (r, x)
256      double *r, *x;
257 {
258   PROTECT_FP_CALL(*r = exp( *x ))
259 }
260 
uuxlog(r,x)261 uuxlog (r, x)
262      double *r, *x;
263 {
264   PROTECT_FP_CALL(*r = log( *x ))
265 }
266 
uuxatan2(r,y,x)267 uuxatan2 (r, y, x)
268      double *r, *y, *x;
269 {
270   PROTECT_FP_CALL(*r = atan2( *y, *x ))
271 }
272