FastRounding.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef __FASTROUNDING__
00023 #define __FASTROUNDING__
00024 
00025 #include "Assert.hxx"
00026 #include <cmath>
00027 #ifdef WIN32
00028 #include <float.h>
00029 #endif
00030 
00031 #if defined (_MSC_VER )
00032 
00036 #if !defined (_DEBUG)
00037 
00087 #define CLAM_ACTIVATE_FAST_ROUNDING \
00088 unsigned CLAM_FPU_STATE_WORD;\
00089 CLAM_FPU_STATE_WORD = _controlfp( 0, 0 );\
00090 
00091 #define CLAM_DEACTIVATE_FAST_ROUNDING \
00092 _controlfp( CLAM_FPU_STATE_WORD, _MCW_RC ); \
00093 
00094 //optimized positive integer chopping routine for Windows, is equivalent to int(a) but much more efficient
00095 inline int Chop( float a )
00096 {
00097         int i;
00098         CLAM_DEBUG_ASSERT( a>=0, "Chop function only for positive numbers" );
00104         _asm {
00105                 fld a
00106                 fistp i
00107         }
00108 
00109         return i;
00110 }
00111 
00112 inline int Round( float a )
00113 {
00114         CLAM_DEBUG_ASSERT(a>=0,"Round function only for positive numbers");
00115         int i;
00116         static const float half = 0.5f;
00122         __asm {
00123                 fld   a
00124                 fadd  half
00125                 fistp i
00126         }
00127 
00128         return i;
00129         
00130 }
00131 
00132 #else // Debug mode
00133 
00134 // MRJ: The macros do nothing on DEBUG
00135 #define CLAM_ACTIVATE_FAST_ROUNDING
00136 #define CLAM_DEACTIVATE_FAST_ROUNDING
00137 
00138 inline int Chop( float a )
00139 {
00140         int i;
00141         CLAM_DEBUG_ASSERT( a>=0, "Chop function only for positive numbers" );
00142         unsigned int saved = _controlfp(0, 0);
00143         _controlfp(_RC_CHOP, _MCW_RC);
00144 
00145         _asm {
00146                 fld a
00147                 fistp i
00148         }
00149 
00150         _controlfp(saved, _MCW_RC);     
00151         return i;
00152 }
00153 
00154 inline int Round( float a )
00155 {
00156         CLAM_DEBUG_ASSERT(a>=0,"Round function only for positive numbers");
00157         int i;
00158         static const float half = 0.5f;
00159 
00160         unsigned int saved = _controlfp(0, 0);
00161         _controlfp(_RC_CHOP, _MCW_RC);
00162         
00163         __asm {
00164                 fld   a
00165                 fadd  half
00166                 fistp i
00167         }
00168         
00169         _controlfp(saved, _MCW_RC);
00170 
00171         return i;
00172         
00173 }
00174 
00175 #endif // End of DEBUG check
00176 
00177 #else // Not Microsoft Visual C
00178 
00179 // The macros don't do anything in compilers other than MSVC
00180 #define CLAM_ACTIVATE_FAST_ROUNDING
00181 #define CLAM_DEACTIVATE_FAST_ROUNDING
00182 
00183 inline int Chop( float a )
00184 {
00185         return int(a);// just hope it's an intrinsic.
00186 }
00187 
00188 inline int Round( float a )
00189 {
00190         #ifdef __USE_ISOC99
00191                 return lrint(a);
00192         #else
00193                 return int(rint(a));
00194         #endif  
00195 }
00196 
00197 #endif
00198 
00199 
00200 #endif // FastRounding.hxx
00201 
Generated by  doxygen 1.6.3