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