CLAM-Development  1.4.0
FastRounding.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #ifndef __FASTROUNDING__
23 #define __FASTROUNDING__
24 
25 #include "Assert.hxx"
26 #include <cmath>
27 #ifdef WIN32
28 #include <float.h>
29 #endif
30 
31 #if defined (_MSC_VER )
32 
36 #if !defined (_DEBUG)
37 
87 #define CLAM_ACTIVATE_FAST_ROUNDING \
88 unsigned CLAM_FPU_STATE_WORD;\
89 CLAM_FPU_STATE_WORD = _controlfp( 0, 0 );\
90 
91 #define CLAM_DEACTIVATE_FAST_ROUNDING \
92 _controlfp( CLAM_FPU_STATE_WORD, _MCW_RC ); \
93 
94 //optimized positive integer chopping routine for Windows, is equivalent to int(a) but much more efficient
95 inline int Chop( float a )
96 {
97  int i;
98  CLAM_DEBUG_ASSERT( a>=0, "Chop function only for positive numbers" );
104  _asm {
105  fld a
106  fistp i
107  }
108 
109  return i;
110 }
111 
112 inline int Round( float a )
113 {
114  CLAM_DEBUG_ASSERT(a>=0,"Round function only for positive numbers");
115  int i;
116  static const float half = 0.5f;
122  __asm {
123  fld a
124  fadd half
125  fistp i
126  }
127 
128  return i;
129 
130 }
131 
132 #else // Debug mode
133 
134 // MRJ: The macros do nothing on DEBUG
135 #define CLAM_ACTIVATE_FAST_ROUNDING
136 #define CLAM_DEACTIVATE_FAST_ROUNDING
137 
138 inline int Chop( float a )
139 {
140  int i;
141  CLAM_DEBUG_ASSERT( a>=0, "Chop function only for positive numbers" );
142  unsigned int saved = _controlfp(0, 0);
143  _controlfp(_RC_CHOP, _MCW_RC);
144 
145  _asm {
146  fld a
147  fistp i
148  }
149 
150  _controlfp(saved, _MCW_RC);
151  return i;
152 }
153 
154 inline int Round( float a )
155 {
156  CLAM_DEBUG_ASSERT(a>=0,"Round function only for positive numbers");
157  int i;
158  static const float half = 0.5f;
159 
160  unsigned int saved = _controlfp(0, 0);
161  _controlfp(_RC_CHOP, _MCW_RC);
162 
163  __asm {
164  fld a
165  fadd half
166  fistp i
167  }
168 
169  _controlfp(saved, _MCW_RC);
170 
171  return i;
172 
173 }
174 
175 #endif // End of DEBUG check
176 
177 #else // Not Microsoft Visual C
178 
179 // The macros don't do anything in compilers other than MSVC
180 #define CLAM_ACTIVATE_FAST_ROUNDING
181 #define CLAM_DEACTIVATE_FAST_ROUNDING
182 
183 inline int Chop( float a )
184 {
185  return int(a);// just hope it's an intrinsic.
186 }
187 
188 inline int Round( float a )
189 {
190  #ifdef __USE_ISOC99
191  return lrint(a);
192  #else
193  return int(rint(a));
194  #endif
195 }
196 
197 #endif
198 
199 
200 #endif // FastRounding.hxx
201