float_cast.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. ** Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
  3. **
  4. ** Permission to use, copy, modify, distribute, and sell this file for any
  5. ** purpose is hereby granted without fee, provided that the above copyright
  6. ** and this permission notice appear in all copies. No representations are
  7. ** made about the suitability of this software for any purpose. It is
  8. ** provided "as is" without express or implied warranty.
  9. */
  10. /* Version 1.1 */
  11. #ifndef FLOAT_CAST_H
  12. #define FLOAT_CAST_H
  13. /*============================================================================
  14. ** On Intel Pentium processors (especially PIII and probably P4), converting
  15. ** from float to int is very slow. To meet the C specs, the code produced by
  16. ** most C compilers targeting Pentium needs to change the FPU rounding mode
  17. ** before the float to int conversion is performed.
  18. **
  19. ** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
  20. ** is this flushing of the pipeline which is so slow.
  21. **
  22. ** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
  23. ** llrint and llrintf which fix this problem as a side effect.
  24. **
  25. ** On Unix-like systems, the configure process should have detected the
  26. ** presence of these functions. If they weren't found we have to replace them
  27. ** here with a standard C cast.
  28. */
  29. /*
  30. ** The C99 prototypes for lrint and lrintf are as follows:
  31. **
  32. ** long int lrintf (float x) ;
  33. ** long int lrint (double x) ;
  34. */
  35. /* The presence of the required functions are detected during the configure
  36. ** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
  37. ** the config.h file.
  38. */
  39. #if (HAVE_LRINTF)
  40. /*#if 0*/
  41. /* These defines enable functionality introduced with the 1999 ISO C
  42. ** standard. They must be defined before the inclusion of math.h to
  43. ** engage them. If optimisation is enabled, these functions will be
  44. ** inlined. With optimisation switched off, you have to link in the
  45. ** maths library using -lm.
  46. */
  47. #define _ISOC9X_SOURCE 1
  48. #define _ISOC99_SOURCE 1
  49. #define __USE_ISOC9X 1
  50. #define __USE_ISOC99 1
  51. #include <math.h>
  52. #define float2int(x) lrintf(x)
  53. #elif (defined(HAVE_LRINT))
  54. #define _ISOC9X_SOURCE 1
  55. #define _ISOC99_SOURCE 1
  56. #define __USE_ISOC9X 1
  57. #define __USE_ISOC99 1
  58. #include <math.h>
  59. #define float2int(x) lrint(x)
  60. #elif (defined (WIN32) || defined (_WIN32))
  61. #include <math.h>
  62. /* Win32 doesn't seem to have these functions.
  63. ** Therefore implement inline versions of these functions here.
  64. */
  65. #ifndef _WIN64
  66. __inline long int
  67. float2int (float flt)
  68. { int intgr;
  69. _asm
  70. { fld flt
  71. fistp intgr
  72. } ;
  73. return intgr ;
  74. }
  75. #else
  76. #define float2int
  77. #endif
  78. #else
  79. #ifdef __GNUC__ /* supported by gcc, but not by all other compilers*/
  80. #warning "Don't have the functions lrint() and lrintf ()."
  81. #warning "Replacing these functions with a standard C cast."
  82. #endif /* __GNUC__ */
  83. #include <math.h>
  84. #define float2int(flt) ((int)(floor(.5+flt)))
  85. #endif
  86. #endif /* FLOAT_CAST_H */