xref: /plan9/sys/src/cmd/gs/src/gxfarith.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1993, 2000 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gxfarith.h,v 1.7 2004/06/23 18:50:19 stefan Exp $ */
18 /* Floating point arithmetic macros for Ghostscript library */
19 
20 #ifndef gxfarith_INCLUDED
21 #  define gxfarith_INCLUDED
22 
23 #include "gconfigv.h"		/* for USE_FPU */
24 #include "gxarith.h"
25 
26 /*
27  * The following macros replace the ones in gxarith.h on machines
28  * that are likely to have very slow floating point.
29  *
30  * None of these macros would be necessary if compilers had a clue
31  * about generating good floating point comparisons on machines with
32  * slow (or no) floating point hardware.
33  */
34 
35 # if USE_FPU <= 0 && arch_floats_are_IEEE && (arch_sizeof_float == arch_sizeof_int || arch_sizeof_float == arch_sizeof_long)
36 
37 #  if arch_sizeof_float == arch_sizeof_int
38 typedef int _f_int_t;
39 typedef uint _f_uint_t;
40 
41 #  else				/* arch_sizeof_float == arch_sizeof_long */
42 typedef long _f_int_t;
43 typedef ulong _f_uint_t;
44 
45 #  endif
46 #  define _f_as_int(f) *(const _f_int_t *)(&(f))
47 #  define _f_as_uint(f) *(const _f_uint_t *)(&(f))
48 
49 #  if arch_sizeof_double == arch_sizeof_int
50 #    define _d_int_t int
51 #  else
52 #   if arch_sizeof_double == arch_sizeof_long
53 #    define _d_int_t long
54 #   endif
55 #  endif
56 #  define _d_uint_t unsigned _d_int_t
57 #  define _d_as_int(f) *(const _d_int_t *)(&(f))
58 #  define _d_as_uint(f) *(const _d_uint_t *)(&(f))
59 
60 #  define _ftest(v,f,n)\
61      (sizeof(v)==sizeof(float)?(f):(n))
62 #  ifdef _d_int_t
63 #    define _fdtest(v,f,d,n)\
64 	(sizeof(v)==sizeof(float)?(f):sizeof(v)==sizeof(double)?(d):(n))
65 #  else
66 #    define _fdtest(v,f,d,n)\
67 	_ftest(v,f,n)
68 #  endif
69 
70 #  undef is_fzero
71 #  define is_fzero(f)	/* must handle both +0 and -0 */\
72      _fdtest(f, (_f_as_int(f) << 1) == 0, (_d_as_int(f) << 1) == 0,\
73        (f) == 0.0)
74 
75 #  undef is_fzero2
76 #  define is_fzero2(f1,f2)\
77      (sizeof(f1) == sizeof(float) && sizeof(f2) == sizeof(float) ?\
78       ((_f_as_int(f1) | _f_as_int(f2)) << 1) == 0 :\
79       (f1) == 0.0 && (f2) == 0.0)
80 
81 #  undef is_fneg
82 #  if arch_is_big_endian
83 #    define _is_fnegb(f) (*(const byte *)&(f) >= 0x80)
84 #  else
85 #    define _is_fnegb(f) (((const byte *)&(f))[sizeof(f) - 1] >= 0x80)
86 #  endif
87 #  if arch_sizeof_float == arch_sizeof_int
88 #    define is_fneg(f)\
89        (sizeof(f) == sizeof(float) ? _f_as_int(f) < 0 :\
90 	_is_fnegb(f))
91 #  else
92 #    define is_fneg(f) _is_fnegb(f)
93 #  endif
94 
95 #  define IEEE_expt 0x7f800000	/* IEEE exponent mask */
96 #  define IEEE_f1 0x3f800000	/* IEEE 1.0 */
97 
98 #  undef is_fge1
99 #  if arch_sizeof_float == arch_sizeof_int
100 #    define is_fge1(f)\
101        (sizeof(f) == sizeof(float) ?\
102 	(_f_as_int(f)) >= IEEE_f1 :\
103 	(f) >= 1.0)
104 #  else				/* arch_sizeof_float == arch_sizeof_long */
105 #    define is_fge1(f)\
106        (sizeof(f) == sizeof(float) ?\
107 	(int)(_f_as_int(f) >> 16) >= (IEEE_f1 >> 16) :\
108 	(f) >= 1.0)
109 #  endif
110 
111 #  undef f_fits_in_ubits
112 #  undef f_fits_in_bits
113 #  define _f_bits(n) (4.0 * (1L << ((n) - 2)))
114 #  define f_fits_in_ubits(f, n)\
115 	_ftest(f, _f_as_uint(f) < (_f_uint_t)IEEE_f1 + ((_f_uint_t)(n) << 23),\
116 	  (f) >= 0 && (f) < _f_bits(n))
117 #  define f_fits_in_bits(f, n)\
118 	_ftest(f, (_f_as_uint(f) & IEEE_expt) < IEEE_f1 + ((_f_uint_t)((n)-1) << 23),\
119 	  (f) >= -_f_bits((n)-1) && (f) < _f_bits((n)-1))
120 
121 # endif				/* USE_FPU <= 0 & ... */
122 
123 /*
124  * Define sine and cosine functions that take angles in degrees rather than
125  * radians, hit exact values at multiples of 90 degrees, and are implemented
126  * efficiently on machines with slow (or no) floating point.
127  */
128 double gs_sin_degrees(double angle);
129 double gs_cos_degrees(double angle);
130 typedef struct gs_sincos_s {
131     double sin, cos;
132     bool orthogonal;		/* angle is multiple of 90 degrees */
133 } gs_sincos_t;
134 void gs_sincos_degrees(double angle, gs_sincos_t * psincos);
135 
136 /*
137  * Define an atan2 function that returns an angle in degrees and uses
138  * the PostScript quadrant rules.  Note that it may return
139  * gs_error_undefinedresult.
140  */
141 int gs_atan2_degrees(double y, double x, double *pangle);
142 
143 #endif /* gxfarith_INCLUDED */
144