gxfarith.h 4.5 KB

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