CLAM-Development
1.1
|
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