00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 #ifndef __SYS_Math__
00140 #define __SYS_Math__
00141
00142 #include "SYS_API.h"
00143 #include <math.h>
00144 #include <limits.h>
00145 #include <float.h>
00146 #include <stdlib.h>
00147 #include "SYS_Types.h"
00148
00149
00150
00151
00152 #if defined(SOLARIS)
00153 #include <sunmath.h>
00154 #endif
00155
00156 #if defined(WIN32) || defined(GAMEOS)
00157 #include "SYS_NTMath.h"
00158 #endif
00159
00160
00161
00162 #define FP32_TOLERANCE ((fpreal32)0.00001)
00163 #define FP64_TOLERANCE ((fpreal64)0.00001)
00164 #define FP32_REAL_MIN ((fpreal32)2e-45)
00165 #define FP64_REAL_MIN ((fpreal64)2e-324)
00166 #define FP32_REAL_MAX ((fpreal32)FLT_MAX)
00167 #define FP64_REAL_MAX ((fpreal64)DBL_MAX)
00168
00169
00170
00171
00172
00173 #define SYS_DBL_DIG 17
00174 #define SYS_FLT_DIG 9
00175
00176
00177 template< typename F >
00178 inline bool SYSisNan(const F f)
00179 {
00180 return(f != f);
00181 }
00182
00183 SYS_API bool SYSisNan(const char *number);
00184
00185 SYS_API bool SYSisInt(const char *str);
00186 SYS_API bool SYSisFloat(const char *str);
00187 SYS_API fpreal32 SYSroundAngle(fpreal32 base, fpreal32 source);
00188 SYS_API fpreal64 SYSroundAngle(fpreal64 base, fpreal64 source);
00189 SYS_API fpreal64 SYSroundAngle(int64 base, int64 source);
00190 SYS_API bool SYSisPrime(uint num);
00191 SYS_API bool SYSisPrime(uint64 num);
00192 SYS_API uint SYSmakePrime(uint num);
00193 SYS_API uint64 SYSmakePrime(uint64 num);
00194 SYS_API uint SYSmakePow2(uint num);
00195 SYS_API uint64 SYSmakePow2(uint64 num);
00196 #if defined(MBSD)
00197 SYS_API size_t SYSmakePow2(size_t num);
00198 #endif
00199
00200 static inline bool SYSisPow2(int n) { return n>0 && !(n&(n-1)); }
00201 static inline bool SYSisPow2(int64 n) { return n>0 && !(n&(n-1)); }
00202 static inline bool SYSisPow2(uint n) { return !(n&(n-1)); }
00203 static inline bool SYSisPow2(uint64 n) { return !(n&(n-1)); }
00204 #if defined(MBSD)
00205 static inline bool SYSisPow2(size_t n) { return !(n&(n-1)); }
00206 #endif
00207
00208 static inline int32 SYSatoi32(const char *buf, int base=10)
00209 {
00210 return base == 10 ? atoi(buf) : strtol(buf, 0, base);
00211 }
00212
00213 static inline uint32 SYSatou32(const char *buf, int base=10)
00214 {
00215 return strtoul(buf, 0, base);
00216 }
00217
00218 static inline int64 SYSatoi64(const char *buf, int base=10)
00219 {
00220 #if defined(WIN32)
00221 return base == 10 ? _atoi64(buf) : _strtoi64(buf, 0, base);
00222 #else
00223 return base == 10 ? atoll(buf) : strtoll(buf, 0, base);
00224 #endif
00225 }
00226
00227 static inline uint64 SYSatou64(const char *buf, int base=10)
00228 {
00229 #if defined(WIN32)
00230 return _strtoui64(buf, 0, base);
00231 #else
00232 return strtoull(buf, 0, base);
00233 #endif
00234 }
00235
00236 static inline int32 SYSstrtoi32(const char *buf) { return strtol(buf, 0, 0); }
00237 static inline uint32 SYSstrtou32(const char *buf) { return strtoul(buf, 0, 0); }
00238 static inline int64 SYSstrtoi64(const char *buf)
00239 {
00240 #if defined(WIN32)
00241 return _strtoi64(buf, 0, 0);
00242 #else
00243 return strtoll(buf, 0, 0);
00244 #endif
00245 }
00246 static inline uint64 SYSstrtou64(const char *buf)
00247 {
00248 #if defined(WIN32)
00249 return _strtoui64(buf, 0, 0);
00250 #else
00251 return strtoull(buf, 0, 0);
00252 #endif
00253 }
00254
00255 static inline fpreal32 SYSatof32(const char *buf)
00256 {
00257 return atof(buf);
00258 }
00259
00260 static inline fpreal64 SYSatof64(const char *buf)
00261 {
00262 return atof(buf);
00263 }
00264
00265 static inline int SYSstrtoi(const char *buf) { return SYSstrtoi32(buf); }
00266 static inline uint SYSstrtou(const char *buf) { return SYSstrtou32(buf); }
00267
00268 static inline int SYSatoi(const char *buf, int base=10)
00269 { return SYSatoi32(buf, base); }
00270 static inline uint SYSatou(const char *buf, int base=10)
00271 { return SYSatou32(buf, base); }
00272 static inline fpreal SYSatof(const char *buf)
00273 { return SYSatof32(buf); }
00274
00275 #if defined(__cplusplus)
00276
00277
00278
00279
00280
00281 #define h_min(a, b) (((a) > (b)) ? (b) : (a))
00282 #define h_argmin(a, b) (((a) > (b)) ? 1 : 0)
00283 #define h_max(a, b) (((a) < (b)) ? (b) : (a))
00284 #define h_argmax(a, b) (((a) < (b)) ? 1 : 0)
00285
00286 #define h_abs(a) (((a) > 0) ? (a) : -(a))
00287
00288 static inline int16 SYSmin(int16 a, int16 b) { return h_min(a,b); }
00289 static inline int16 SYSmax(int16 a, int16 b) { return h_max(a,b); }
00290 static inline int16 SYSabs(int16 a) { return h_abs(a); }
00291 static inline int SYSargmin(int16 a, int16 b) { return h_argmin(a,b);}
00292 static inline int SYSargmax(int16 a, int16 b) { return h_argmax(a,b);}
00293 static inline int32 SYSmin(int32 a, int32 b) { return h_min(a,b); }
00294 static inline int32 SYSmax(int32 a, int32 b) { return h_max(a,b); }
00295 static inline int32 SYSabs(int32 a) { return h_abs(a); }
00296 static inline int SYSargmin(int32 a, int32 b) { return h_argmin(a,b);}
00297 static inline int SYSargmax(int32 a, int32 b) { return h_argmax(a,b);}
00298 static inline int64 SYSmin(int64 a, int64 b) { return h_min(a,b); }
00299 static inline int64 SYSmax(int64 a, int64 b) { return h_max(a,b); }
00300 static inline int64 SYSmin(int32 a, int64 b) { return h_min(a,b); }
00301 static inline int64 SYSmax(int32 a, int64 b) { return h_max(a,b); }
00302 static inline int64 SYSmin(int64 a, int32 b) { return h_min(a,b); }
00303 static inline int64 SYSmax(int64 a, int32 b) { return h_max(a,b); }
00304 static inline int64 SYSabs(int64 a) { return h_abs(a); }
00305 static inline int SYSargmin(int64 a, int64 b) { return h_argmin(a,b);}
00306 static inline int SYSargmax(int64 a, int64 b) { return h_argmax(a,b);}
00307 static inline uint16 SYSmin(uint16 a, uint16 b) { return h_min(a,b); }
00308 static inline uint16 SYSmax(uint16 a, uint16 b) { return h_max(a,b); }
00309 static inline int SYSargmin(uint16 a, uint16 b) { return h_argmin(a,b);}
00310 static inline int SYSargmax(uint16 a, uint16 b) { return h_argmax(a,b);}
00311 static inline uint32 SYSmin(uint32 a, uint32 b) { return h_min(a,b); }
00312 static inline uint32 SYSmax(uint32 a, uint32 b) { return h_max(a,b); }
00313 static inline int SYSargmin(uint32 a, uint32 b) { return h_argmin(a,b);}
00314 static inline int SYSargmax(uint32 a, uint32 b) { return h_argmax(a,b);}
00315 static inline uint64 SYSmin(uint64 a, uint64 b) { return h_min(a,b); }
00316 static inline uint64 SYSmax(uint64 a, uint64 b) { return h_max(a,b); }
00317 static inline int SYSargmin(uint64 a, uint64 b) { return h_argmin(a,b);}
00318 static inline int SYSargmax(uint64 a, uint64 b) { return h_argmax(a,b);}
00319 static inline fpreal16 SYSmin(fpreal16 a, fpreal16 b) { return h_min(a,b); }
00320 static inline fpreal16 SYSmax(fpreal16 a, fpreal16 b) { return h_max(a,b); }
00321 static inline int SYSargmin(fpreal16 a, fpreal16 b){ return h_argmin(a,b);}
00322 static inline int SYSargmax(fpreal16 a, fpreal16 b){ return h_argmax(a,b);}
00323 static inline fpreal32 SYSmin(fpreal32 a, fpreal32 b) { return h_min(a,b); }
00324 static inline fpreal32 SYSmax(fpreal32 a, fpreal32 b) { return h_max(a,b); }
00325 static inline int SYSargmin(fpreal32 a, fpreal32 b){ return h_argmin(a,b);}
00326 static inline int SYSargmax(fpreal32 a, fpreal32 b){ return h_argmax(a,b);}
00327 static inline fpreal64 SYSmin(fpreal64 a, fpreal64 b) { return h_min(a,b); }
00328 static inline fpreal64 SYSmax(fpreal64 a, fpreal64 b) { return h_max(a,b); }
00329 static inline int SYSargmin(fpreal64 a, fpreal64 b){ return h_argmin(a,b);}
00330 static inline int SYSargmax(fpreal64 a, fpreal64 b){ return h_argmax(a,b);}
00331
00332
00333 #if (defined(LINUX) && defined(IA64)) || defined(MBSD)
00334 static inline size_t SYSmin(size_t a, size_t b) { return h_min(a,b); }
00335 static inline size_t SYSmax(size_t a, size_t b) { return h_max(a,b); }
00336 static inline int SYSargmin(size_t a, size_t b) { return h_argmin(a,b);}
00337 static inline int SYSargmax(size_t a, size_t b) { return h_argmax(a,b);}
00338 #endif
00339
00340 #undef h_min
00341 #undef h_max
00342 #undef h_abs
00343
00344 #define h_clamp(val, min, max, tol) \
00345 ((val <= min+tol) ? min : ((val >= max-tol) ? max : val))
00346
00347 static inline int
00348 SYSclamp(int v, int min, int max)
00349 { return h_clamp(v, min, max, 0); }
00350
00351 static inline uint
00352 SYSclamp(uint v, uint min, uint max)
00353 { return h_clamp(v, min, max, 0); }
00354
00355 static inline int64
00356 SYSclamp(int64 v, int64 min, int64 max)
00357 { return h_clamp(v, min, max, CONST_INT64(0)); }
00358
00359 static inline uint64
00360 SYSclamp(uint64 v, uint64 min, uint64 max)
00361 { return h_clamp(v, min, max, CONST_UINT64(0)); }
00362
00363 static inline fpreal32
00364 SYSclamp(fpreal32 v, fpreal32 min, fpreal32 max, fpreal32 tol=(fpreal32)0)
00365 { return h_clamp(v, min, max, tol); }
00366
00367 static inline fpreal64
00368 SYSclamp(fpreal64 v, fpreal64 min, fpreal64 max, fpreal64 tol=(fpreal64)0)
00369 { return h_clamp(v, min, max, tol); }
00370
00371 #undef h_clamp
00372
00373 #define SYS_UNARY(func) \
00374 static inline fpreal64 SYS##func(fpreal64 arg) { return func(arg); } \
00375 static inline fpreal32 SYS##func(fpreal32 arg) { return func##f(arg); } \
00376 static inline fpreal64 SYS##func(int64 arg) { return func((fpreal64)arg); } \
00377 static inline fpreal64 SYS##func(int32 arg) { return func((fpreal64)arg); }
00378
00379
00380 #define cbrtf(x) cbrt(x)
00381 #define hypotf(x,y) hypot((x),(y))
00382
00383 #define SYS_BINARY(func) \
00384 static inline fpreal64 SYS##func(fpreal64 a, fpreal64 b) { return func(a,b); } \
00385 static inline fpreal32 SYS##func(fpreal32 a, fpreal32 b) \
00386 { return func##f(a, b); }
00387
00388 SYS_UNARY(sin)
00389 SYS_UNARY(cos)
00390 SYS_UNARY(tan)
00391 SYS_UNARY(sinh)
00392 SYS_UNARY(cosh)
00393 SYS_UNARY(tanh)
00394 SYS_UNARY(sqrt)
00395 SYS_UNARY(trunc)
00396 SYS_UNARY(cbrt)
00397 SYS_UNARY(exp)
00398 SYS_BINARY(fmod)
00399 SYS_BINARY(pow)
00400 SYS_BINARY(atan2)
00401 SYS_BINARY(hypot)
00402
00403 static inline fpreal32 SYSsafediv(fpreal32 x, fpreal32 y)
00404 { return y != 0 ? x/y : 0; }
00405 static inline fpreal64 SYSsafediv(fpreal64 x, fpreal64 y)
00406 { return y != 0 ? x/y : 0; }
00407 static inline fpreal32 SYSsafesqrt(fpreal32 x)
00408 { return x > 0 ? SYSsqrt(x) : 0; }
00409 static inline fpreal64 SYSsafesqrt(fpreal64 x)
00410 { return x > 0 ? SYSsqrt(x) : 0; }
00411
00412 static inline fpreal32 SYSlog(fpreal32 v) { return v <= 0 ? 0:logf(v); }
00413 static inline fpreal32 SYSlog(fpreal64 v) { return v <= 0 ? 0:log(v); }
00414 static inline fpreal32 SYSlog10(fpreal32 v) { return v <= 0 ? 0:log10f(v); }
00415 static inline fpreal32 SYSlog10(fpreal64 v) { return v <= 0 ? 0:log10(v); }
00416
00417 #if defined(WIN32)
00418 static inline fpreal32 SYSexpm1(fpreal32 x) { return SYSexp(x) - 1; }
00419 static inline fpreal64 SYSexpm1(fpreal64 x) { return SYSexp(x) - 1; }
00420 static inline fpreal32 SYSlog1p(fpreal32 x) { return SYSlog(x+1); }
00421 static inline fpreal64 SYSlog1p(fpreal64 x) { return SYSexp(x+1); }
00422 #else
00423 SYS_UNARY(expm1)
00424 SYS_UNARY(log1p)
00425 #endif
00426
00427 #undef SYS_UNARY
00428 #undef SYS_BINARY
00429 #undef cbrtf
00430 #undef hypotf
00431
00432 static inline fpreal32 SYSabs(fpreal32 a) { return fabsf(a); }
00433 static inline fpreal32 SYSabs(fpreal64 a) { return fabs(a); }
00434 static inline fpreal32 SYSfabs(fpreal32 a) { return fabsf(a); }
00435 static inline fpreal32 SYSfabs(fpreal64 a) { return fabs(a); }
00436
00437 #include "SYS_Floor.h"
00438
00439 static inline fpreal32 SYSasin(fpreal32 a)
00440 { return asinf(SYSclamp(a, (fpreal32)-1, (fpreal32)1)); }
00441 static inline fpreal32 SYSacos(fpreal32 a)
00442 { return acosf(SYSclamp(a, (fpreal32)-1, (fpreal32)1)); }
00443 static inline fpreal32 SYSatan(fpreal32 a)
00444 { return atanf(a); }
00445 static inline fpreal32 SYSatan(fpreal32 y, fpreal32 x)
00446 { return atan2f(y, x); }
00447 static inline fpreal64 SYSasin(fpreal64 a)
00448 { return asin (SYSclamp(a, (fpreal64)-1, (fpreal64)1)); }
00449 static inline fpreal64 SYSacos(fpreal64 a)
00450 { return acos (SYSclamp(a, (fpreal64)-1, (fpreal64)1)); }
00451 static inline fpreal64 SYSatan(fpreal64 a)
00452 { return atan (a); }
00453 static inline fpreal64 SYSatan(fpreal64 y, fpreal64 x)
00454 { return atan2(y, x); }
00455
00456 static inline fpreal32 SYSdegToRad(fpreal32 a) { return a*(fpreal32)(M_PI/180.0); }
00457 static inline fpreal64 SYSdegToRad(fpreal64 a) { return a*(fpreal64)(M_PI/180.0); }
00458 static inline fpreal64 SYSdegToRad(int64 a) { return a*(fpreal64)(M_PI/180.0); }
00459
00460 static inline fpreal32 SYSradToDeg(fpreal32 a) { return a*(fpreal32)(180.0/M_PI); }
00461 static inline fpreal64 SYSradToDeg(fpreal64 a) { return a*(fpreal64)(180.0/M_PI); }
00462 static inline fpreal64 SYSradToDeg(int64 a) { return a*(fpreal64)(180.0/M_PI); }
00463
00464 #define h_compare(func, code) \
00465 static inline bool func(fpreal32 a, fpreal32 b, \
00466 fpreal32 tol=FP32_TOLERANCE) \
00467 { return code; } \
00468 static inline bool func(fpreal64 a, fpreal64 b, \
00469 fpreal64 tol=FP64_TOLERANCE) \
00470 { return code; }
00471
00472 static inline bool
00473 SYSequalZero(fpreal32 a, fpreal32 tol=FP32_TOLERANCE)
00474 { return a >= -tol && a <= tol; }
00475
00476 static inline bool
00477 SYSequalZero(fpreal64 a, fpreal64 tol=FP64_TOLERANCE)
00478 { return a >= -tol && a <= tol; }
00479
00480 static inline bool
00481 SYSequalZero(int64 a, fpreal64 tol=FP64_TOLERANCE)
00482 { return a >= -tol && a <= tol; }
00483
00484
00485 h_compare(SYSisEqual, SYSabs(a-b)<=tol)
00486 h_compare(SYSisGreater, (a-b) > tol)
00487 h_compare(SYSisGreaterOrEqual, (a-b) >= -tol)
00488 h_compare(SYSisLess, (a-b) < -tol)
00489 h_compare(SYSisLessOrEqual, (a-b) <= tol)
00490
00491 inline bool SYSisEqual(int64 a, int64 b) { return a == b; }
00492 inline bool SYSisGreater(int64 a, int64 b) { return a > b; }
00493 inline bool SYSisGreaterOrEqual(int64 a, int64 b) { return a >= b; }
00494 inline bool SYSisLess(int64 a, int64 b) { return a < b; }
00495 inline bool SYSisLessOrEqual(int64 a, int64 b) { return a <= b; }
00496
00497 #undef h_compare
00498
00499 static inline bool
00500 SYSalmostEqual(fpreal32 a, fpreal32 b, int ulps=50)
00501 {
00502 SYS_FPReal32Union ai, bi;
00503 ai.fval = a;
00504 bi.fval = b;
00505 if (ai.ival < 0)
00506 ai.ival = 0x80000000 - ai.ival;
00507 if (bi.ival < 0)
00508 bi.ival = 0x80000000 - bi.ival;
00509 return SYSabs(ai.ival-bi.ival) <= ulps;
00510 }
00511
00512 static inline bool
00513 SYSalmostEqual(fpreal64 a, fpreal64 b, int64 ulps)
00514 {
00515 SYS_FPReal64Union ai, bi;
00516 ai.fval = a;
00517 bi.fval = b;
00518 if (ai.ival < 0)
00519 ai.ival = CONST_INT64(0x8000000000000000) - ai.ival;
00520 if (bi.ival < 0)
00521 bi.ival = CONST_INT64(0x8000000000000000) - bi.ival;
00522 return SYSabs(ai.ival-bi.ival) <= ulps;
00523 }
00524
00525 static inline bool
00526 SYSalmostEqual(fpreal64 a, fpreal64 b, int32 ulps=50)
00527 {
00528 return SYSalmostEqual(a, b, (int64)ulps);
00529 }
00530
00531 #define h_max3(type) \
00532 static inline type \
00533 SYSmax(type v0, type v1, type v2) { \
00534 if (v1 > v0) v0 = v1; \
00535 return SYSmax(v2, v0); \
00536 }
00537 #define h_max4(type) \
00538 static inline type \
00539 SYSmax(type v0, type v1, type v2, type v3) { \
00540 if (v1 > v0) v0 = v1; \
00541 if (v2 > v0) v0 = v2; \
00542 return SYSmax(v3, v0); \
00543 }
00544 #define h_argmax3(type) \
00545 static inline int \
00546 SYSargmax(type v0, type v1, type v2) { \
00547 if (v1 > v0) return SYSargmax(v1, v2) + 1; \
00548 if (v2 > v0) return 2; \
00549 return 0; \
00550 }
00551 #define h_argmax4(type) \
00552 static inline int \
00553 SYSargmax(type v0, type v1, type v2, type v3) { \
00554 if (v1 > v0) return SYSargmax(v1, v2, v3) + 1; \
00555 if (v2 > v0) return SYSargmax(v2, v3) + 2; \
00556 if (v3 > v0) return 3; \
00557 return 0; \
00558 }
00559 #define h_min3(type) \
00560 static inline type \
00561 SYSmin(type v0, type v1, type v2) { \
00562 if (v1 < v0) v0 = v1; \
00563 return SYSmin(v2, v0); \
00564 }
00565 #define h_min4(type) \
00566 static inline type \
00567 SYSmin(type v0, type v1, type v2, type v3) { \
00568 if (v1 < v0) v0 = v1; \
00569 if (v2 < v0) v0 = v2; \
00570 return SYSmin(v3, v0); \
00571 }
00572 #define h_argmin3(type) \
00573 static inline int \
00574 SYSargmin(type v0, type v1, type v2) { \
00575 if (v1 < v0) return SYSargmin(v1, v2) + 1; \
00576 if (v2 < v0) return 2; \
00577 return 0; \
00578 }
00579 #define h_argmin4(type) \
00580 static inline int \
00581 SYSargmin(type v0, type v1, type v2, type v3) { \
00582 if (v1 < v0) return SYSargmin(v1, v2, v3) + 1; \
00583 if (v2 < v0) return SYSargmin(v2, v3) + 2; \
00584 if (v3 < v0) return 3; \
00585 return 0; \
00586 }
00587
00588
00589 #define h_max(type) h_min3(type) h_min4(type) h_max3(type) h_max4(type) \
00590 h_argmin3(type) h_argmin4(type) \
00591 h_argmax3(type) h_argmax4(type)
00592
00593 #define h_avg3(type) \
00594 static inline type \
00595 SYSavg(type v0, type v1, type v2) { \
00596 return (v0+v1+v2) * ((type)(1.0/3.0)); \
00597 }
00598 #define h_avg4(type) \
00599 static inline type \
00600 SYSavg(type v0, type v1, type v2, type v3) { \
00601 return (v0+v1+v2+v3) * ((type)0.25); \
00602 }
00603
00604 #define h_avg(type) h_avg3(type) h_avg4(type)
00605
00606 h_max(int8)
00607 h_max(uint8)
00608 h_max(int16)
00609 h_max(uint16)
00610 h_max(int32)
00611 h_max(uint32)
00612 h_max(int64)
00613 h_max(uint64)
00614 h_max(fpreal32) h_avg(fpreal32)
00615 h_max(fpreal64) h_avg(fpreal64)
00616
00617 static inline int64
00618 SYSavg(int64 a, int64 b, int64 c)
00619 { return (a + b + c + 1) / 3; }
00620 static inline int64
00621 SYSavg(int64 a, int64 b, int64 c, int64 d)
00622 { return (a + b + c + d + 2) / 4; }
00623
00624
00625 #if (defined(LINUX) && defined(IA64)) || defined(MBSD)
00626 h_max(size_t)
00627 #endif
00628
00629 #undef h_min3
00630 #undef h_min4
00631 #undef h_max3
00632 #undef h_max4
00633 #undef h_argmin3
00634 #undef h_argmin4
00635 #undef h_argmax3
00636 #undef h_argmax4
00637 #undef h_avg3
00638 #undef h_avg4
00639 #undef h_max
00640 #undef h_avg
00641
00642
00643
00644 static inline fpreal32
00645 SYSlerp(fpreal32 v1, fpreal32 v2, fpreal32 t)
00646 {
00647 return v1 + (v2 - v1)*t;
00648 }
00649
00650 static inline fpreal64
00651 SYSlerp(fpreal64 v1, fpreal64 v2, fpreal64 t)
00652 {
00653 return v1 + (v2 - v1)*t;
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 static inline fpreal32
00667 SYSbilerp(fpreal32 u0v0, fpreal32 u1v0, fpreal32 u0v1, fpreal32 u1v1,
00668 fpreal32 u, fpreal32 v)
00669 {
00670 return SYSlerp(SYSlerp(u0v0, u0v1, v), SYSlerp(u1v0, u1v1, v), u);
00671 }
00672
00673 static inline fpreal64
00674 SYSbilerp(fpreal64 u0v0, fpreal64 u1v0, fpreal64 u0v1, fpreal64 u1v1,
00675 fpreal64 u, fpreal64 v)
00676 {
00677 return SYSlerp(SYSlerp(u0v0, u0v1, v), SYSlerp(u1v0, u1v1, v), u);
00678 }
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 static inline fpreal32
00692 SYSbarycentric(fpreal32 v0, fpreal32 v1, fpreal32 v2, fpreal32 u, fpreal32 v)
00693 {
00694 return v0*(1-u-v) + v1*u + v2*v;
00695 }
00696
00697 static inline fpreal64
00698 SYSbarycentric(fpreal64 v0, fpreal64 v1, fpreal64 v2, fpreal64 u, fpreal64 v)
00699 {
00700 return v0*(1-u-v) + v1*u + v2*v;
00701 }
00702
00703
00704 static inline fpreal32
00705 SYSsmooth(fpreal32 min, fpreal32 max, fpreal32 val)
00706 {
00707 fpreal32 t;
00708 if (val <= min) return 0;
00709 if (val >= max) return 1;
00710 t = max - min;
00711 if (SYSequalZero(t, (fpreal32)1e-8)) return (fpreal32).5;
00712 t = (val - min) / t;
00713 return t*t*((fpreal32)3.0 - (fpreal32)2.0*t);
00714 }
00715
00716 static inline fpreal64
00717 SYSsmooth(fpreal64 min, fpreal64 max, fpreal64 val)
00718 {
00719 fpreal64 t;
00720 if (val <= min) return 0;
00721 if (val >= max) return 1;
00722 t = max - min;
00723 if (SYSequalZero(t, (fpreal64)1e-18)) return (fpreal64).5;
00724 t = (val - min) / t;
00725 return t*t*((fpreal64)3.0 - (fpreal64)2.0*t);
00726 }
00727
00728 static inline fpreal32
00729 SYSsmooth(fpreal32 min, fpreal32 max, fpreal32 value, fpreal32 roll)
00730 {
00731 fpreal32 f;
00732 if (roll > 0)
00733 {
00734 f = SYSsmooth(min, max, value);
00735 return roll < (fpreal32)1 ? (fpreal32)1-SYSpow((fpreal32)1-f,
00736 (fpreal32)1/roll) : SYSpow(f, roll);
00737 }
00738 return (fpreal32)1;
00739 }
00740
00741 static inline fpreal64
00742 SYSsmooth(fpreal64 min, fpreal64 max, fpreal64 value, fpreal64 roll)
00743 {
00744 fpreal64 f;
00745 if (roll > 0)
00746 {
00747 f = SYSsmooth(min, max, value);
00748 return roll < (fpreal64)1 ? (fpreal64)1-SYSpow((fpreal64)1-f,
00749 (fpreal64)1/roll) : SYSpow(f, roll);
00750 }
00751 return (fpreal64)1;
00752 }
00753
00754 static inline fpreal32
00755 SYSfit(fpreal32 val, fpreal32 omin, fpreal32 omax, fpreal32 nmin, fpreal32 nmax)
00756 {
00757 fpreal32 d = omax - omin;
00758 if (SYSequalZero(d, (fpreal32)1e-8))
00759 return (nmin+nmax)*(fpreal32).5;
00760 if (omin < omax)
00761 {
00762 if (val < omin) return nmin;
00763 if (val > omax) return nmax;
00764 }
00765 else
00766 {
00767 if (val < omax) return nmax;
00768 if (val > omin) return nmin;
00769 }
00770 return nmin + (nmax-nmin)*(val-omin)/d;
00771 }
00772
00773 static inline fpreal64
00774 SYSfit(fpreal64 val, fpreal64 omin, fpreal64 omax, fpreal64 nmin, fpreal64 nmax)
00775 {
00776 fpreal64 d = omax - omin;
00777 if (SYSequalZero(d, (fpreal64)1e-18))
00778 return (nmin+nmax)*(fpreal64).5;
00779 if (omin < omax)
00780 {
00781 if (val < omin) return nmin;
00782 if (val > omax) return nmax;
00783 }
00784 else
00785 {
00786 if (val < omax) return nmax;
00787 if (val > omin) return nmin;
00788 }
00789 return nmin + (nmax-nmin)*(val-omin)/d;
00790 }
00791
00792 static inline fpreal32
00793 SYSfit01(fpreal32 val, fpreal32 nmin, fpreal32 nmax)
00794 {
00795 if (val < 0) return nmin;
00796 if (val > 1) return nmax;
00797 return SYSlerp(nmin, nmax, val);
00798 }
00799
00800 static inline fpreal64
00801 SYSfit01(fpreal64 val, fpreal64 nmin, fpreal64 nmax)
00802 {
00803 if (val < 0) return nmin;
00804 if (val > 1) return nmax;
00805 return SYSlerp(nmin, nmax, val);
00806 }
00807
00808 static inline fpreal32
00809 SYSroundDownToMultipleOf(fpreal32 val, fpreal32 multiple)
00810 {
00811 fpreal32 modulus;
00812 fpreal32 retval;
00813 if (SYSequalZero(multiple))
00814 return val;
00815 modulus = SYSfmod(val, multiple);
00816 if (SYSequalZero(modulus) || SYSequalZero(modulus-multiple))
00817 return val;
00818 retval = val - modulus;
00819 if( val < (fpreal32)0 && modulus!=(fpreal32)0 )
00820 retval -= multiple;
00821 return retval;
00822 }
00823
00824 static inline fpreal64
00825 SYSroundDownToMultipleOf(fpreal64 val, fpreal64 multiple)
00826 {
00827 fpreal64 modulus;
00828 fpreal64 retval;
00829 if (SYSequalZero(multiple))
00830 return val;
00831 modulus = SYSfmod(val, multiple);
00832 if (SYSequalZero(modulus) || SYSequalZero(modulus-multiple))
00833 return val;
00834 retval = val - modulus;
00835 if( val < (fpreal64)0 && modulus!=(fpreal64)0 )
00836 retval -= multiple;
00837 return retval;
00838 }
00839
00840 static inline fpreal32
00841 SYSroundUpToMultipleOf(fpreal32 val, fpreal32 multiple)
00842 {
00843 fpreal32 modulus;
00844 if (SYSequalZero(multiple))
00845 return val;
00846 modulus = SYSfmod(val, multiple);
00847 if (SYSequalZero(modulus) || SYSequalZero(modulus-multiple))
00848 return val;
00849 if (val > (fpreal32)0)
00850 val += multiple;
00851 return val - modulus;
00852 }
00853
00854 static inline fpreal64
00855 SYSroundUpToMultipleOf(fpreal64 val, fpreal64 multiple)
00856 {
00857 fpreal64 modulus;
00858 if (SYSequalZero(multiple))
00859 return val;
00860 modulus = SYSfmod(val, multiple);
00861 if (SYSequalZero(modulus) || SYSequalZero(modulus-multiple))
00862 return val;
00863 if (val > (fpreal64)0)
00864 val += multiple;
00865 return val - modulus;
00866 }
00867
00868 static inline uint32
00869 SYSwang_inthash(uint32 key)
00870 {
00871
00872 key += ~(key << 16);
00873 key ^= (key >> 5);
00874 key += (key << 3);
00875 key ^= (key >> 13);
00876 key += ~(key << 9);
00877 key ^= (key >> 17);
00878 return key;
00879 }
00880
00881 static inline uint32
00882 SYSmultiplicative_inthash(uint32 key)
00883 {
00884
00885
00886
00887 return key * 2654435761u;
00888 }
00889
00890 static inline uint64
00891 SYSwang_inthash64(uint64 key)
00892 {
00893
00894 key += ~(key << 32);
00895 key ^= (key >> 22);
00896 key += ~(key << 13);
00897 key ^= (key >> 8);
00898 key += (key << 3);
00899 key ^= (key >> 15);
00900 key += ~(key << 27);
00901 key ^= (key >> 31);
00902 return key;
00903 }
00904
00905 static inline uint
00906 SYSreal_hash(fpreal32 a, int lowmask=0xf)
00907 {
00908 SYS_FPReal32Union ai;
00909 ai.fval = a;
00910 return SYSwang_inthash(ai.uval & (~lowmask));
00911 }
00912
00913 static inline uint
00914 SYSreal_hash(fpreal64 a, int lowmask=0xf)
00915 {
00916 SYS_FPReal64Union ai;
00917 int32 lo, hi;
00918 ai.fval = a;
00919 lo = ai.uval & 0xfffffff;
00920 hi = ai.uval >> 32;
00921 return SYSwang_inthash(lo & (~lowmask)) ^ SYSwang_inthash(hi);
00922 }
00923
00924 static inline uint
00925 SYSvector_hash(const int32 *vector, int size)
00926 {
00927 uint hash = size;
00928 for (int i = 0; i < size; ++i)
00929 hash = hash*37 + SYSwang_inthash(vector[i]);
00930 return hash;
00931 }
00932
00933 static inline uint
00934 SYSvector_hash(const int64 *vector, int size)
00935 {
00936 uint hash = size;
00937 for (int i = 0; i < size; ++i)
00938 hash = hash*37 + SYSwang_inthash64(vector[i]);
00939 return hash;
00940 }
00941
00942
00943 static inline uint
00944 SYSvector_hash(const fpreal32 *vector, int size)
00945 {
00946 uint hash = size;
00947 for (int i = 0; i < size; ++i)
00948 hash = hash*37 + SYSreal_hash(vector[i]);
00949 return hash;
00950 }
00951
00952 static inline uint
00953 SYSvector_hash(const fpreal64 *vector, int size)
00954 {
00955 uint hash = size;
00956 for (int i = 0; i < size; ++i)
00957 hash = hash*37 + SYSreal_hash(vector[i]);
00958 return hash;
00959 }
00960
00961 static inline uint
00962 SYSpointerHash(const void *ptr)
00963 {
00964 #if SIZEOF_VOID_P == 8
00965
00966 return (uint)((int64)ptr & 0xffffffff);
00967 #else
00968
00969 return (uint)ptr;
00970 #endif
00971 }
00972
00973
00974 inline static fpreal32
00975 SYSfastRandom(uint &seed)
00976 {
00977 SYS_FPReal32Union tmp;
00978 seed = seed*1664525 + 1013904223;
00979 tmp.uval = 0x3f800000 | (0x007fffff & seed);
00980 return tmp.fval-1.0F;
00981 }
00982
00983 inline static fpreal32
00984 SYSrandom(uint &seed)
00985 {
00986 SYS_FPReal32Union tmp;
00987 seed = seed*1664525 + 1013904223;
00988 tmp.uval = SYSwang_inthash(seed);
00989 tmp.uval = 0x3f800000 | (0x007fffff & tmp.uval);
00990 return tmp.fval - 1.0F;
00991 }
00992
00993 inline static uint
00994 SYSfastRandomInt(uint &seed)
00995 {
00996 seed = seed*1664525 + 1013904223;
00997 return SYSwang_inthash(seed);
00998 }
00999
01000 inline static fpreal32
01001 SYSfastRandomZero(uint &seed)
01002 {
01003 SYS_FPReal32Union tmp;
01004 seed = seed*1664525 + 1013904223;
01005 tmp.uval = 0x3f800000 | (0x007fffff & seed);
01006 return tmp.fval - 1.5F;
01007 }
01008
01009 inline static fpreal32
01010 SYSrandomZero(uint &seed)
01011 {
01012 SYS_FPReal32Union tmp;
01013 seed = seed*1664525 + 1013904223;
01014 tmp.uval = SYSwang_inthash(seed);
01015 tmp.uval = 0x3f800000 | (0x007fffff & tmp.uval);
01016 return tmp.fval - 1.5F;
01017 }
01018
01019
01020
01021 inline static void
01022 SYSminmax(fpreal32 v0, fpreal32 v1, fpreal32 v2, fpreal32 v3,
01023 fpreal32 &min, fpreal32 &max)
01024 {
01025 if (v0 < v1) { min = v0; max = v1; }
01026 else { min = v1; max = v0; }
01027 if (v2 < v3)
01028 {
01029 if (v2 < min) min = v2;
01030 if (v3 > max) max = v3;
01031 }
01032 else
01033 {
01034 if (v2 > max) max = v2;
01035 if (v3 < min) min = v3;
01036 }
01037 }
01038
01039 inline static void
01040 SYSminmax(fpreal64 v0, fpreal64 v1, fpreal64 v2, fpreal64 v3,
01041 fpreal64 &min, fpreal64 &max)
01042 {
01043 if (v0 < v1) { min = v0; max = v1; }
01044 else { min = v1; max = v0; }
01045 if (v2 < v3)
01046 {
01047 if (v2 < min) min = v2;
01048 if (v3 > max) max = v3;
01049 }
01050 else
01051 {
01052 if (v2 > max) max = v2;
01053 if (v3 < min) min = v3;
01054 }
01055 }
01056
01057 inline static void
01058 SYSminmax(fpreal32 v0, fpreal32 v1, fpreal32 v2, fpreal32 &min, fpreal32 &max)
01059 {
01060 if (v0 < v1) { min = v0; max = v1; }
01061 else { min = v1; max = v0; }
01062 if (v2 < min) { min = v2; }
01063 else if (v2 > max) { max = v2; }
01064 }
01065
01066 inline static void
01067 SYSminmax(fpreal64 v0, fpreal64 v1, fpreal64 v2, fpreal64 &min, fpreal64 &max)
01068 {
01069 if (v0 < v1) { min = v0; max = v1; }
01070 else { min = v1; max = v0; }
01071 if (v2 < min) { min = v2; }
01072 else if (v2 > max) { max = v2; }
01073 }
01074
01075 inline static void
01076 SYSgetSinCosFromSlope(fpreal32 slope, fpreal32 &sintheta, fpreal32 &costheta)
01077 {
01078 fpreal32 one_over_m;
01079 sintheta = slope / SYSsqrt(slope*slope + (fpreal32)1);
01080 if ((slope = SYSabs(slope)) > (fpreal32)1)
01081 {
01082 one_over_m = (fpreal32)1 / slope;
01083 costheta = one_over_m / SYSsqrt(one_over_m*one_over_m + 1);
01084 }
01085 else
01086 costheta = SYSsqrt((fpreal32)1 - sintheta*sintheta);
01087 }
01088
01089 inline static void
01090 SYSgetSinCosFromSlope(fpreal64 slope, fpreal64 &sintheta, fpreal64 &costheta)
01091 {
01092 fpreal64 one_over_m;
01093 sintheta = slope / SYSsqrt(slope*slope + (fpreal64)1);
01094 if ((slope = SYSabs(slope)) > (fpreal64)1)
01095 {
01096 one_over_m = (fpreal64)1 / slope;
01097 costheta = one_over_m / SYSsqrt(one_over_m*one_over_m + 1);
01098 }
01099 else
01100 costheta = SYSsqrt((fpreal64)1 - sintheta*sintheta);
01101 }
01102
01103 inline static bool
01104 SYSsameSign( fpreal32 v0, fpreal32 v1 )
01105 {
01106 return (v0*v1)>0;
01107 }
01108
01109 inline static bool
01110 SYSsameSign( fpreal64 v0, fpreal64 v1 )
01111 {
01112 return (v0*v1)>0;
01113 }
01114
01115 inline static bool
01116 SYSsameSign( int32 v0, int32 v1 )
01117 {
01118 return (v0 ^ v1) >= 0;
01119 }
01120
01121 inline static bool
01122 SYSsameSign( int64 v0, int64 v1 )
01123 {
01124 return (v0 ^ v1) >= 0;
01125 }
01126
01127 static inline uint SYSnextPrime(uint num) { return SYSmakePrime(num+1); }
01128
01129 static inline int SYShexCharToInt(char c)
01130 {
01131
01132
01133 if (c >= '0' && c <= '9')
01134 return c - '0';
01135 if (c >= 'a' && c <= 'f')
01136 return c - 'a' + 10;
01137 if (c >= 'A' && c <= 'F')
01138 return c - 'A' + 10;
01139 return -1;
01140 }
01141
01142 static inline char SYSintToHexChar(int value)
01143 {
01144
01145 return value < 10 ? '0' + value : 'a' + value - 10;
01146 }
01147
01148 SYS_API void SYSsort(int &a, int &b);
01149 SYS_API void SYSsort(int &a, int &b, int &c);
01150 SYS_API void SYSsort(int64 &a, int64 &b);
01151 SYS_API void SYSsort(int64 &a, int64 &b, int64 &c);
01152 SYS_API void SYSsort(float &a, float &b);
01153 SYS_API void SYSsort(float &a, float &b, float &c);
01154 SYS_API void SYSsort(double &a, double &b);
01155 SYS_API void SYSsort(double &a, double &b, double &c);
01156
01157
01158 #include "SYS_MathPermute.h"
01159 #include "SYS_MathRestrictive.h"
01160
01161 #else
01162 #define SYSmax(a,b) ((a) > (b) ? (a) : (b))
01163 #define SYSmin(a,b) ((a) < (b) ? (a) : (b))
01164 #define SYSabs(a) ((a) < 0 ? (a) : -(a))
01165 #endif
01166
01167 #endif