Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShFractionImpl.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2005 Serious Hack Inc.
00004 // 
00005 // This software is provided 'as-is', without any express or implied
00006 // warranty. In no event will the authors be held liable for any damages
00007 // arising from the use of this software.
00008 // 
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it
00011 // freely, subject to the following restrictions:
00012 // 
00013 // 1. The origin of this software must not be misrepresented; you must
00014 // not claim that you wrote the original software. If you use this
00015 // software in a product, an acknowledgment in the product documentation
00016 // would be appreciated but is not required.
00017 // 
00018 // 2. Altered source versions must be plainly marked as such, and must
00019 // not be misrepresented as being the original software.
00020 // 
00021 // 3. This notice may not be removed or altered from any source
00022 // distribution.
00024 #ifndef SHFRACTIONALIMPL_HPP
00025 #define SHFRACTIONALIMPL_HPP
00026 
00027 #include <cmath>
00028 #include "ShMath.hpp"
00029 #include "ShFraction.hpp"
00030 
00031 namespace SH {
00032 
00033 #define _CompType typename ShFraction<T>::CompType 
00034 #define _LongType typename ShFraction<T>::LongType 
00035 #define _SignedLongType typename ShFraction<T>::SignedLongType 
00036 
00037 // @todo replace uses of std::fabs 
00038 
00039 template<typename T/* @todo clamp , bool Clamp */>
00040 ShFraction<T>::ShFraction()
00041 {}
00042 
00043 template<typename T/* @todo clamp , bool Clamp */>
00044 ShFraction<T>::ShFraction(double value)
00045   : m_val(clamp_val(value))
00046 {
00047 }
00048 
00049 template<typename T/* @todo clamp , bool Clamp */>
00050 ShFraction<T> ShFraction<T>::make_fraction(CompType value)
00051 {
00052   ShFraction result;
00053   result.m_val = clamp_val(value);
00054   return result; 
00055 }
00056 
00057 template<typename T/* @todo clamp , bool Clamp */>
00058 ShFraction<T> ShFraction<T>::make_fraction_signed(SignedLongType value)
00059 {
00060   ShFraction result;
00061   result.m_val = clamp_val_signed(value);
00062   return result; 
00063 }
00064 
00065 template<typename T/* @todo clamp , bool Clamp */>
00066 template<typename T2>
00067 ShFraction<T>::ShFraction(const ShFraction<T2> &other)
00068   : m_val(clamp_val(other.get_double())) 
00069 {
00070 }
00071 
00073 template<typename T/* @todo clamp , bool Clamp */>
00074 ShFraction<T>::operator double() const
00075 {
00076   return get_double(); 
00077 }
00078 
00079 template<typename T/* @todo clamp , bool Clamp */>
00080 T& ShFraction<T>::val()
00081 {
00082   return m_val;
00083 }
00084 
00085 template<typename T/* @todo clamp , bool Clamp */>
00086 T ShFraction<T>::val() const
00087 {
00088   return m_val;
00089 }
00090 
00092 template<typename T/* @todo clamp , bool Clamp */>
00093 ShFraction<T>& ShFraction<T>::operator=(double value)
00094 {
00095   m_val = clamp_val(value);
00096   return *this;
00097 }
00098 
00099 template<typename T/* @todo clamp , bool Clamp */>
00100 ShFraction<T>& ShFraction<T>::operator=(const ShFraction& other)
00101 {
00102   m_val = other.m_val;
00103   return *this;
00104 }
00105 
00106 template<typename T/* @todo clamp , bool Clamp */>
00107 ShFraction<T>& ShFraction<T>::operator+=(double value)
00108 {
00109   return operator+=(ShFraction(value));
00110 }
00111 
00112 template<typename T/* @todo clamp , bool Clamp */>
00113 ShFraction<T>& ShFraction<T>::operator+=(const ShFraction& other)
00114 {
00115   m_val = clamp_val(CompType(m_val) + CompType(other.m_val));
00116   return *this;
00117 }
00118 
00119 template<typename T/* @todo clamp , bool Clamp */>
00120 ShFraction<T>& ShFraction<T>::operator-=(double value)
00121 {
00122   return operator-=(ShFraction(value));
00123 }
00124 
00125 template<typename T/* @todo clamp , bool Clamp */>
00126 ShFraction<T>& ShFraction<T>::operator-=(const ShFraction& other)
00127 {
00128   m_val = clamp_val_signed(SignedLongType(m_val) - SignedLongType(other.m_val));
00129   return *this;
00130 }
00131 
00132 template<typename T/* @todo clamp , bool Clamp */>
00133 ShFraction<T>& ShFraction<T>::operator*=(double value)
00134 {
00135   return operator*=(ShFraction(value)); 
00136 }
00137 
00138 template<typename T/* @todo clamp , bool Clamp */>
00139 ShFraction<T>& ShFraction<T>::operator*=(const ShFraction& other)
00140 {
00141   m_val = clamp_val(CompType(m_val) * CompType(other.m_val));
00142   return *this;
00143 }
00144 
00145 template<typename T/* @todo clamp , bool Clamp */>
00146 ShFraction<T>& ShFraction<T>::operator/=(double value)
00147 {
00148   return operator/=(ShFraction(value)); 
00149 }
00150 
00151 template<typename T/* @todo clamp , bool Clamp */>
00152 ShFraction<T>& ShFraction<T>::operator/=(const ShFraction& other)
00153 {
00154   LongType numerator = LongType(m_val) << BITS;   
00155   LongType denom = LongType(other.m_val);
00156   m_val = clamp_val(numerator / denom);
00157   return (*this); 
00158 }
00159 
00160 template<typename T/* @todo clamp , bool Clamp */>
00161 ShFraction<T>& ShFraction<T>::operator%=(double value)
00162 {
00163   return operator%=(ShFraction(value));
00164 }
00165 
00166 template<typename T/* @todo clamp , bool Clamp */>
00167 ShFraction<T>& ShFraction<T>::operator%=(const ShFraction& other)
00168 {
00169   // @todo range - should need no clamping for this
00170   m_val = m_val % other.m_val;
00171   if(m_val < 0) m_val += other.m_val;
00172 }
00173 
00175 template<typename T/* @todo clamp , bool Clamp */>
00176 ShFraction<T> ShFraction<T>::operator-() const 
00177 {
00178   if(is_signed /* @todo clamp && Clamp */) return make_fraction(0); 
00179   return make_fraction(-m_val);
00180 }
00181 
00182 template<typename TT>
00183 std::ostream& operator<<(std::ostream &out, const ShFraction<TT> &value)
00184 {
00185   out << double(value);
00186   return out;
00187 }
00188 
00189 template<typename TT>
00190 std::istream& operator>>(std::istream &in, ShFraction<TT> &value)
00191 {
00192   double temp;
00193   in >> temp;
00194   value = temp;
00195   return in;
00196 }
00197 
00198 template<typename T/* @todo clamp , bool Clamp */>
00199 inline
00200 double ShFraction<T>::get_double() const
00201 {
00202   return double(m_val) / double(ONE);
00203 }
00204 
00205 template<typename T/* @todo clamp , bool Clamp */>
00206 inline
00207 T ShFraction<T>::clamp_val(double value)
00208 {
00209   double temp = value * ONE;
00210 
00211 /* @todo clamp  if(Clamp) { */
00212     temp = std::max(std::min(temp, double(MAX)), double(MIN));
00213 /* @todo clamp  } */
00214   return T(temp);
00215 }
00216 
00217 template<typename T/* @todo clamp , bool Clamp */>
00218 inline
00219 T ShFraction<T>::clamp_val(CompType value)
00220 {
00221   /* @todo clamp if(Clamp) { */
00222     value = std::max(std::min(value, CompType(MAX)), CompType(MIN));
00223   /* @todo clamp } */
00224   return T(value);
00225 }
00226 
00227 template<typename T/* @todo clamp , bool Clamp */>
00228 inline
00229 T ShFraction<T>::clamp_val_signed(SignedLongType value)
00230 {
00231   /* @todo clamp if(Clamp) { */
00232     value = std::max(std::min(value, SignedLongType(MAX)), SignedLongType(MIN));
00233   /* @todo clamp } */
00234   return T(value);
00235 }
00236 
00238 template<typename T/* @todo clamp , bool Clamp */>
00239 ShFraction<T> operator+(const ShFraction<T> &a, const ShFraction<T> &b) 
00240 {
00241   return ShFraction<T>::make_fraction(_CompType(a.m_val) + _CompType(b.m_val));
00242 }
00243 
00244 
00245 template<typename T/* @todo clamp , bool Clamp */>
00246 ShFraction<T> operator-(const ShFraction<T> &a, const ShFraction<T> &b) 
00247 {
00248   return ShFraction<T>::make_fraction_signed(
00249       _SignedLongType(a.m_val) - 
00250       _SignedLongType(b.m_val));
00251 }
00252 
00253 template<typename T/* @todo clamp , bool Clamp */>
00254 ShFraction<T> operator*(const ShFraction<T> &a, const ShFraction<T> &b) 
00255 {
00256   return ShFraction<T>::make_fraction(_CompType(a.m_val) * _CompType(b.m_val));
00257 }
00258 
00259 
00260 template<typename T/* @todo clamp , bool Clamp */>
00261 ShFraction<T> operator/(const ShFraction<T> &a, const ShFraction<T> &b) 
00262 {
00263   _LongType numerator = _LongType(a.m_val) << ShFraction<T>::BITS;   
00264   _LongType denom = _LongType(b.m_val);
00265   return ShFraction<T>::make_fraction(numerator / denom);
00266 }
00267 
00268 
00269 template<typename T/* @todo clamp , bool Clamp */>
00270 ShFraction<T> operator%(const ShFraction<T> &a, const ShFraction<T> &b) 
00271 {
00272   T temp = a.m_val % b.m_val;
00273   if(temp < 0) temp += b.m_val; 
00274   return ShFraction<T>(temp);
00275 }
00276 
00277 template<typename T/* @todo clamp , bool Clamp */>
00278 ShFraction<T> cbrt(const ShFraction<T> &a) 
00279 {
00280   return ShFraction<T>(std::pow(double(a), 1.0 / 3.0)); 
00281 }
00282 
00283 
00284 template<typename T/* @todo clamp , bool Clamp */>
00285 ShFraction<T> exp(const ShFraction<T> &a) 
00286 {
00287   return ShFraction<T>(std::exp(double(a))); 
00288 }
00289 
00290 
00291 template<typename T/* @todo clamp , bool Clamp */>
00292 ShFraction<T> exp2(const ShFraction<T> &a) 
00293 {
00294   return ShFraction<T>(std::pow(2.0, double(a))); 
00295 }
00296 
00297 
00298 template<typename T/* @todo clamp , bool Clamp */>
00299 ShFraction<T> exp10(const ShFraction<T> &a) 
00300 {
00301   return ShFraction<T>(std::pow(10.0, double(a))); 
00302 }
00303 
00304 
00305 template<typename T/* @todo clamp , bool Clamp */>
00306 ShFraction<T> log(const ShFraction<T> &a) 
00307 {
00308   return ShFraction<T>(std::log(double(a))); 
00309 }
00310 
00311 
00312 template<typename T/* @todo clamp , bool Clamp */>
00313 ShFraction<T> log2(const ShFraction<T> &a) 
00314 {
00315   return ShFraction<T>(log2f(double(a))); 
00316 }
00317 
00318 
00319 template<typename T/* @todo clamp , bool Clamp */>
00320 ShFraction<T> log10(const ShFraction<T> &a) 
00321 {
00322   return ShFraction<T>(log10f(double(a))); 
00323 }
00324 
00325 template<typename T/* @todo clamp , bool Clamp */>
00326 ShFraction<T> frac(const ShFraction<T> &a)
00327 {
00328   T result = a.m_val;
00329   if(result < 0) {
00330     result += ShFraction<T>::ONE;
00331   }
00332   return ShFraction<T>(result);
00333 }
00334 
00335 template<typename T/* @todo clamp , bool Clamp */>
00336 ShFraction<T> fmod(const ShFraction<T> &a, const ShFraction<T> &b) 
00337 {
00338   return a % b;
00339 }
00340 
00341 
00342 template<typename T/* @todo clamp , bool Clamp */>
00343 ShFraction<T> pow(const ShFraction<T> &a, const ShFraction<T> &b) 
00344 {
00345   // @todo check if this is optimal
00346   // @todo do integer special cases? - see NuS.cc
00347   return ShFraction<T>(std::pow(double(a), double(b))); 
00348 }
00349 
00350 
00351 // not a good function for fractional types...
00352 // guaranteed to overflow...DOH
00353 template<typename T/* @todo clamp , bool Clamp */>
00354 ShFraction<T> rcp(const ShFraction<T> &a) 
00355 {
00356   if(a.m_val > 0) return ShFraction<T>(ShFraction<T>::MAX);
00357   return ShFraction<T>(ShFraction<T>::MIN);
00358 }
00359 
00360 template<typename T/* @todo clamp , bool Clamp */>
00361 ShFraction<T> rsq(const ShFraction<T> &a) 
00362 {
00363   return rcp(a); // same bad behaviour 
00364 }
00365 
00366 template<typename T/* @todo clamp , bool Clamp */>
00367 ShFraction<T> sgn(const ShFraction<T> &a) 
00368 {
00369   return ShFraction<T>(a.m_val > 0 ? 1 : a.m_val == 0 ? 0 : -1); 
00370 }
00371 
00372 template<typename T/* @todo clamp , bool Clamp */>
00373 ShFraction<T> sqrt(const ShFraction<T> &a) 
00374 {
00375   return ShFraction<T>(std::sqrt(double(a)));
00376 }
00377 
00378 
00380 template<typename T/* @todo clamp , bool Clamp */>
00381 ShFraction<T> acos(const ShFraction<T> &a) 
00382 {
00383   return ShFraction<T>(std::acos(double(a)));
00384 }
00385 
00386 
00387 template<typename T/* @todo clamp , bool Clamp */>
00388 ShFraction<T> asin(const ShFraction<T> &a) 
00389 {
00390   return ShFraction<T>(std::asin(double(a)));
00391 }
00392 
00393 
00394 template<typename T/* @todo clamp , bool Clamp */>
00395 ShFraction<T> atan(const ShFraction<T> &a) 
00396 {
00397   return ShFraction<T>(std::atan(double(a)));
00398 }
00399 
00400 
00401 template<typename T/* @todo clamp , bool Clamp */>
00402 ShFraction<T> atan2(const ShFraction<T> &a, const ShFraction<T> &b) 
00403 {
00404   return ShFraction<T>(std::atan2(double(a), double(b)));
00405 }
00406 
00407 
00408 template<typename T/* @todo clamp , bool Clamp */>
00409 ShFraction<T> cos(const ShFraction<T> &a) 
00410 {
00411   return ShFraction<T>(std::cos(double(a)));
00412 }
00413 
00414 template<typename T/* @todo clamp , bool Clamp */>
00415 ShFraction<T> sin(const ShFraction<T> &a) 
00416 {
00417   return ShFraction<T>(std::sin(double(a)));
00418 }
00419 
00420 
00421 template<typename T/* @todo clamp , bool Clamp */>
00422 ShFraction<T> tan(const ShFraction<T> &a) 
00423 {
00424   return ShFraction<T>(std::tan(double(a)));
00425 }
00426 
00427 
00429 template<typename T/* @todo clamp , bool Clamp */>
00430 bool operator<(const ShFraction<T> &a, const ShFraction<T> &b) 
00431 {
00432   return (a.m_val < b.m_val);
00433 }
00434 
00435 template<typename T/* @todo clamp , bool Clamp */>
00436 bool operator<=(const ShFraction<T> &a, const ShFraction<T> &b) 
00437 {
00438   return (a.m_val <= b.m_val);
00439 }
00440 
00441 template<typename T/* @todo clamp , bool Clamp */>
00442 bool operator>(const ShFraction<T> &a, const ShFraction<T> &b) 
00443 {
00444   return (a.m_val > b.m_val);
00445 }
00446 
00447 template<typename T/* @todo clamp , bool Clamp */>
00448 bool operator>=(const ShFraction<T> &a, const ShFraction<T> &b) 
00449 {
00450   return (a.m_val >= b.m_val);
00451 }
00452 
00453 template<typename T/* @todo clamp , bool Clamp */>
00454 bool operator==(const ShFraction<T> &a, const ShFraction<T> &b) 
00455 {
00456   return (a.m_val == b.m_val);
00457 }
00458 
00459 template<typename T/* @todo clamp , bool Clamp */>
00460 bool operator!=(const ShFraction<T> &a, const ShFraction<T> &b) 
00461 {
00462   return (a.m_val != b.m_val);
00463 }
00464 
00466 template<typename T/* @todo clamp , bool Clamp */>
00467 ShFraction<T> min(const ShFraction<T> &a, const ShFraction<T> &b) 
00468 {
00469   return ShFraction<T>(std::min(a.m_val, b.m_val));
00470 }
00471 
00472 template<typename T/* @todo clamp , bool Clamp */>
00473 ShFraction<T> max(const ShFraction<T> &a, const ShFraction<T> &b) 
00474 {
00475   return ShFraction<T>(std::max(a.m_val, b.m_val));
00476 }
00477 
00478 template<typename T/* @todo clamp , bool Clamp */>
00479 ShFraction<T> floor(const ShFraction<T> &a) 
00480 {
00481 
00482   T result = 0; 
00483   if(a.m_val == ShFraction<T>::ONE) {
00484     result = ShFraction<T>::ONE;
00485   } else if(ShFraction<T>::is_signed && a.m_val < 0) {
00486     a.m_val = -ShFraction<T>::ONE;
00487   }
00488   return ShFraction<T>(result); 
00489 }
00490 
00491 template<typename T/* @todo clamp , bool Clamp */>
00492 ShFraction<T> ceil(const ShFraction<T> &a) 
00493 {
00494   T ONE = ShFraction<T>::ONE;
00495   T result = 0; 
00496   if(a.m_val > 0) {
00497     result = ONE;
00498   } else if(ShFraction<T>::is_signed && 
00499       a.m_val == -ONE) {
00500     result = -ONE;
00501   }
00502   return ShFraction<T>(result);
00503 }
00504 
00505 template<typename T/* @todo clamp , bool Clamp */>
00506 ShFraction<T> rnd(const ShFraction<T> &a) 
00507 {
00508   T ONE = ShFraction<T>::ONE;
00509   T HALF = ONE >> 1; // slightly less than half
00510   T result;
00511   if(a.m_val > HALF) {
00512     result = ONE;
00513   } else if(!ShFraction<T>::is_signed || result > -HALF) {
00514     result = 0;
00515   } else {
00516     result = -ONE;
00517   }
00518   return ShFraction<T>(result); 
00519 }
00520 
00521 template<typename T/* @todo clamp , bool Clamp */>
00522 ShFraction<T> abs(const ShFraction<T> &a) 
00523 {
00524   return ShFraction<T>(a.m_val < 0 ? -a.m_val: a.m_val);
00525 }
00526 
00528 template<typename T/* @todo clamp , bool Clamp */>
00529 ShFraction<T> cond(const ShFraction<T> &a, const ShFraction<T> &b, 
00530     const ShFraction<T> &c)
00531 {
00532   return ShFraction<T>(a.m_val > 0 ? b.m_val: c.m_val); 
00533 }
00534 
00535 template<typename T/* @todo clamp , bool Clamp */>
00536 ShFraction<T> lerp(const ShFraction<T> &a, const ShFraction<T> &b, const ShFraction<T> &c) 
00537 {
00538   T ONE = ShFraction<T>(ShFraction<T>::ONE);
00539   return a * b + (ONE - a) * c;
00540 }
00541 
00542 #undef _CompType
00543 #undef _LongType
00544 #undef _SignedLongType
00545 }
00546 
00547 #endif

Generated on Wed Jun 15 18:12:39 2005 for Sh by  doxygen 1.4.3-20050530