itom 2.2.1
|
00001 /* ******************************************************************** 00002 itom software 00003 URL: http://www.uni-stuttgart.de/ito 00004 Copyright (C) 2016, Institut fuer Technische Optik (ITO), 00005 Universitaet Stuttgart, Germany 00006 00007 This file is part of itom and its software development toolkit (SDK). 00008 00009 itom is free software; you can redistribute it and/or modify it 00010 under the terms of the GNU Library General Public Licence as published by 00011 the Free Software Foundation; either version 2 of the Licence, or (at 00012 your option) any later version. 00013 00014 In addition, as a special exception, the Institut fuer Technische 00015 Optik (ITO) gives you certain additional rights. 00016 These rights are described in the ITO LGPL Exception version 1.0, 00017 which can be found in the file LGPL_EXCEPTION.txt in this package. 00018 00019 itom is distributed in the hope that it will be useful, but 00020 WITHOUT ANY WARRANTY; without even the implied warranty of 00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library 00022 General Public Licence for more details. 00023 00024 You should have received a copy of the GNU Library General Public License 00025 along with itom. If not, see <http://www.gnu.org/licenses/>. 00026 *********************************************************************** */ 00027 00028 #ifndef NUMERIC_H 00029 #define NUMERIC_H 00030 00031 #include "typeDefs.h" 00032 #include "color.h" 00033 #include <limits> 00034 00035 namespace ito 00036 { 00038 00047 template<typename _Tp> inline bool isNotZero(_Tp value) 00048 { 00049 return !(value == 0); 00050 } 00051 00053 template<> inline bool isNotZero<float32>(float32 value) 00054 { 00055 if (fabs(value) < std::numeric_limits<float32>::epsilon()) 00056 return false; 00057 else 00058 return true; 00059 } 00060 00062 template<> inline bool isNotZero<float64>(float64 value) 00063 { 00064 if (fabs(value) < std::numeric_limits<float64>::epsilon()) 00065 return false; 00066 else 00067 return true; 00068 } 00069 00070 00072 00081 template<typename _Tp> inline bool isFinite(_Tp /*value*/) 00082 { 00083 return true; 00084 } 00085 00087 template<> inline bool isFinite<float32>(float32 value) 00088 { 00089 unsigned char *ch = (unsigned char *)&value; 00090 return (ch[3] & 0x7f) != 0x7f || (ch[2] & 0x80) != 0x80; 00091 } 00092 00094 template<> inline bool isFinite<float64>(float64 value) 00095 { 00096 unsigned char *ch = (unsigned char *)&value; 00097 return (ch[7] & 0x7f) != 0x7f || (ch[6] & 0xf0) != 0xf0; 00098 } 00099 00101 template<> inline bool isFinite<complex64>(complex64 value) 00102 { 00103 float32 realVal = value.real(); 00104 float32 imagVal = value.real(); 00105 unsigned char *chreal = (unsigned char *)&realVal; 00106 unsigned char *chimag = (unsigned char *)&imagVal; 00107 return ((chreal[3] & 0x7f) != 0x7f || (chreal[2] & 0x80) != 0x80) && ((chimag[3] & 0x7f) != 0x7f || (chimag[2] & 0x80) != 0x80); 00108 } 00109 00111 template<> inline bool isFinite<complex128>(complex128 value) 00112 { 00113 float64 realVal = value.real(); 00114 float64 imagVal = value.real(); 00115 unsigned char *chreal = (unsigned char *)&realVal; 00116 unsigned char *chimag = (unsigned char *)&imagVal; 00117 return ((chreal[7] & 0x7f) != 0x7f || (chreal[6] & 0xf0) != 0xf0) && ((chimag[7] & 0x7f) != 0x7f || (chimag[6] & 0xf0) != 0xf0); 00118 } 00119 00121 00130 template<typename _Tp> inline bool isNaN(_Tp value) 00131 { 00132 return false; 00133 } 00134 00136 template<> inline bool isNaN<float32>(float32 value) 00137 { 00138 unsigned char *ch = (unsigned char *)&value; 00139 return (ch[3] & 0x7f) == 0x7f && ch[2] > 0x80; 00140 } 00142 template<> inline bool isNaN<float64>(float64 value) 00143 { 00144 unsigned char *ch = (unsigned char *)&value; 00145 return (ch[7] & 0x7f) == 0x7f && ch[6] > 0xf0; 00146 } 00147 00149 template<> inline bool isNaN<complex64>(complex64 value) 00150 { 00151 float32 realVal = value.real(); 00152 float32 imagVal = value.real(); 00153 unsigned char *chreal = (unsigned char *)&realVal; 00154 unsigned char *chimag = (unsigned char *)&imagVal; 00155 return ((chreal[3] & 0x7f) == 0x7f && chreal[2] > 0x80) || ((chimag[3] & 0x7f) == 0x7f && chimag[2] > 0x80); 00156 } 00157 00159 template<> inline bool isNaN<complex128>(complex128 value) 00160 { 00161 float64 realVal = value.real(); 00162 float64 imagVal = value.real(); 00163 unsigned char *chreal = (unsigned char *)&realVal; 00164 unsigned char *chimag = (unsigned char *)&imagVal; 00165 return ((chreal[7] & 0x7f) == 0x7f && chreal[6] > 0xf0) || ((chimag[7] & 0x7f) == 0x7f && chimag[6] > 0xf0); 00166 } 00167 00169 00178 template<typename _Tp> inline bool isInf(_Tp /*value*/) 00179 { 00180 return false; 00181 } 00182 00184 template<> inline bool isInf<float32>(float32 value) 00185 { 00186 unsigned char *ch = (unsigned char *)&value; 00187 return (ch[3] & 0x7f) == 0x7f && ch[2] == 0x80; 00188 } 00189 00191 template<> inline bool isInf<float64>(float64 value) 00192 { 00193 unsigned char *ch = (unsigned char *)&value; 00194 return (ch[7] & 0x7f) == 0x7f && ch[6] == 0xf0; 00195 } 00196 00198 template<> inline bool isInf<complex64>(complex64 value) 00199 { 00200 float32 realVal = value.real(); 00201 float32 imagVal = value.real(); 00202 unsigned char *chreal = (unsigned char *)&realVal; 00203 unsigned char *chimag = (unsigned char *)&imagVal; 00204 return ((chreal[3] & 0x7f) == 0x7f && chreal[2] == 0x80) || ((chimag[3] & 0x7f) == 0x7f && chimag[2] == 0x80); 00205 } 00206 00208 template<> inline bool isInf<complex128>(complex128 value) 00209 { 00210 float64 realVal = value.real(); 00211 float64 imagVal = value.real(); 00212 unsigned char *chreal = (unsigned char *)&realVal; 00213 unsigned char *chimag = (unsigned char *)&imagVal; 00214 return ((chreal[7] & 0x7f) == 0x7f && chreal[6] == 0xf0) || ((chimag[7] & 0x7f) == 0x7f && chimag[6] == 0xf0); 00215 } 00216 00218 00228 template<typename _Tp> inline bool isZeroValue(_Tp v, _Tp /*epsilon*/) 00229 { 00230 return v == 0; 00231 } 00232 00233 template<> inline bool isZeroValue(Rgba32 v, Rgba32 /*epsilon*/) 00234 { 00235 return v == Rgba32::zeros(); 00236 } 00237 00238 template<> inline bool isZeroValue(float32 v, float32 epsilon) 00239 { 00240 return v >= epsilon ? false : (v <= -epsilon ? false : true); 00241 } 00242 00243 template<> inline bool isZeroValue(float64 v, float64 epsilon) 00244 { 00245 return v >= epsilon ? false : (v <= -epsilon ? false : true); 00246 } 00247 00248 template<> inline bool isZeroValue(std::complex<ito::float32> v, std::complex<ito::float32> epsilon) 00249 { 00250 return isZeroValue<ito::float32>(v.real(), epsilon.real()) && isZeroValue<ito::float32>(v.imag(), epsilon.real()); 00251 } 00252 00253 template<> inline bool isZeroValue(std::complex<ito::float64> v, std::complex<ito::float64> epsilon) 00254 { 00255 return isZeroValue<ito::float64>(v.real(), epsilon.real()) && isZeroValue<ito::float64>(v.imag(), epsilon.real()); 00256 } 00257 00258 00260 00263 template<typename _Tp> inline bool areEqual(_Tp a, _Tp b) 00264 { 00265 //for fixed-point and Rgba32 data types 00266 return a == b; 00267 } 00268 00269 template<> inline bool areEqual(float32 a, float32 b) 00270 { 00271 return fabs(a - b) < std::numeric_limits<float32>::epsilon(); 00272 } 00273 00274 template<> inline bool areEqual(float64 a, float64 b) 00275 { 00276 return fabs(a - b) < std::numeric_limits<float64>::epsilon(); 00277 } 00278 00279 template<> inline bool areEqual(complex64 a, complex64 b) 00280 { 00281 return areEqual<ito::float32>(a.real(), b.real()) && areEqual<ito::float32>(a.imag(), b.imag()); 00282 } 00283 00284 template<> inline bool areEqual(complex128 a, complex128 b) 00285 { 00286 return areEqual<ito::float64>(a.real(), b.real()) && areEqual<ito::float64>(a.imag(), b.imag()); 00287 } 00288 00289 00290 } // namespace ito 00291 00292 #endif // NUMERIC_H