Dynamic allocation before VBR
[opus.git] / libcelt / float_cast.h
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
11 /* Version 1.1 */
12
13 #ifndef FLOAT_CAST_H
14 #define FLOAT_CAST_H
15
16 /*============================================================================ 
17 **      On Intel Pentium processors (especially PIII and probably P4), converting
18 **      from float to int is very slow. To meet the C specs, the code produced by 
19 **      most C compilers targeting Pentium needs to change the FPU rounding mode 
20 **      before the float to int conversion is performed. 
21 **
22 **      Changing the FPU rounding mode causes the FPU pipeline to be flushed. It 
23 **      is this flushing of the pipeline which is so slow.
24 **
25 **      Fortunately the ISO C99 specifications define the functions lrint, lrintf,
26 **      llrint and llrintf which fix this problem as a side effect. 
27 **
28 **      On Unix-like systems, the configure process should have detected the 
29 **      presence of these functions. If they weren't found we have to replace them 
30 **      here with a standard C cast.
31 */
32
33 /*      
34 **      The C99 prototypes for lrint and lrintf are as follows:
35 **      
36 **              long int lrintf (float x) ;
37 **              long int lrint  (double x) ;
38 */
39
40 /*      The presence of the required functions are detected during the configure
41 **      process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
42 **      the config.h file.
43 */
44
45 #if (HAVE_LRINTF)
46 /*#if 0*/
47
48         /*      These defines enable functionality introduced with the 1999 ISO C
49         **      standard. They must be defined before the inclusion of math.h to
50         **      engage them. If optimisation is enabled, these functions will be 
51         **      inlined. With optimisation switched off, you have to link in the
52         **      maths library using -lm.
53         */
54
55         #define _ISOC9X_SOURCE  1
56         #define _ISOC99_SOURCE  1
57
58         #define __USE_ISOC9X    1
59         #define __USE_ISOC99    1
60
61         #include        <math.h>
62         #define float2int(x) lrintf(x)
63
64 #elif (defined(HAVE_LRINT))
65
66 #define _ISOC9X_SOURCE  1
67 #define _ISOC99_SOURCE  1
68
69 #define __USE_ISOC9X    1
70 #define __USE_ISOC99    1
71
72 #include        <math.h>
73 #define float2int(x) lrint(x)
74
75 #elif (defined (WIN32) || defined (_WIN32))
76
77         #include        <math.h>
78
79         /*      Win32 doesn't seem to have these functions. 
80         **      Therefore implement inline versions of these functions here.
81         */
82         
83         __inline long int 
84         float2int (float flt)
85         {       int intgr;
86
87                 _asm
88                 {       fld flt
89                         fistp intgr
90                         } ;
91                         
92                 return intgr ;
93         }
94
95 #else
96
97 #ifdef __GNUC__ /* supported by gcc, but not by all other compilers*/
98         #warning "Don't have the functions lrint() and lrintf ()."
99         #warning "Replacing these functions with a standard C cast."
100 #endif /* __GNUC__ */
101
102         #include        <math.h>
103
104         #define float2int(flt)          ((int)(floor(.5+flt)))
105
106 #endif
107
108
109 #endif /* FLOAT_CAST_H */