diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-09 11:34:21 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-09 13:44:59 -0700 |
| commit | fcf83dbf9effab3bd98bad2b83b2468b7eb05cfd (patch) | |
| tree | 41047c94883b86ec085a81597391ce3ef557cd43 /source/core/slang-math.h | |
| parent | 52e8d4b9a27ab0060f874c3a63ab531847be35c0 (diff) | |
Initial import of code.
Diffstat (limited to 'source/core/slang-math.h')
| -rw-r--r-- | source/core/slang-math.h | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/source/core/slang-math.h b/source/core/slang-math.h new file mode 100644 index 000000000..454dfbfdf --- /dev/null +++ b/source/core/slang-math.h @@ -0,0 +1,220 @@ +#ifndef CORE_LIB_MATH_H +#define CORE_LIB_MATH_H + +#include <math.h> + +namespace CoreLib +{ + namespace Basic + { + class Math + { + public: + static const float Pi; + template<typename T> + static T Min(const T& v1, const T&v2) + { + return v1<v2?v1:v2; + } + template<typename T> + static T Max(const T& v1, const T&v2) + { + return v1>v2?v1:v2; + } + template<typename T> + static T Min(const T& v1, const T&v2, const T&v3) + { + return Min(v1, Min(v2, v3)); + } + template<typename T> + static T Max(const T& v1, const T&v2, const T&v3) + { + return Max(v1, Max(v2, v3)); + } + template<typename T> + static T Clamp(const T& val, const T& vmin, const T&vmax) + { + if (val < vmin) return vmin; + else if (val > vmax) return vmax; + else return val; + } + + static inline int FastFloor(float x) + { + int i = (int)x; + return i - (i > x); + } + + static inline int FastFloor(double x) + { + int i = (int)x; + return i - (i > x); + } + + static inline int IsNaN(float x) + { +#ifdef _M_X64 + return _isnanf(x); +#else + return isnan(x); +#endif + } + + static inline int IsInf(float x) + { + return isinf(x); + } + + static inline unsigned int Ones32(register unsigned int x) + { + /* 32-bit recursive reduction using SWAR... + but first step is mapping 2-bit values + into sum of 2 1-bit values in sneaky way + */ + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + return(x & 0x0000003f); + } + + static inline unsigned int Log2Floor(register unsigned int x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return(Ones32(x >> 1)); + } + + static inline unsigned int Log2Ceil(register unsigned int x) + { + int y = (x & (x - 1)); + y |= -y; + y >>= (32 - 1); + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return(Ones32(x >> 1) - y); + } + /* + static inline int Log2(float x) + { + unsigned int ix = (unsigned int&)x; + unsigned int exp = (ix >> 23) & 0xFF; + int log2 = (unsigned int)(exp) - 127; + + return log2; + } + */ + }; + inline int FloatAsInt(float val) + { + union InterCast + { + float fvalue; + int ivalue; + } cast; + cast.fvalue = val; + return cast.ivalue; + } + inline float IntAsFloat(int val) + { + union InterCast + { + float fvalue; + int ivalue; + } cast; + cast.ivalue = val; + return cast.fvalue; + } + + inline unsigned short FloatToHalf(float val) + { + int x = *(int*)&val; + unsigned short bits = (x >> 16) & 0x8000; + unsigned short m = (x >> 12) & 0x07ff; + unsigned int e = (x >> 23) & 0xff; + if (e < 103) + return bits; + if (e > 142) + { + bits |= 0x7c00u; + bits |= e == 255 && (x & 0x007fffffu); + return bits; + } + if (e < 113) + { + m |= 0x0800u; + bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1); + return bits; + } + bits |= ((e - 112) << 10) | (m >> 1); + bits += m & 1; + return bits; + } + + inline float HalfToFloat(unsigned short input) + { + union InterCast + { + float fvalue; + int ivalue; + InterCast() = default; + InterCast(int ival) + { + ivalue = ival; + } + }; + static const InterCast magic = InterCast((127 + (127 - 15)) << 23); + static const InterCast was_infnan = InterCast((127 + 16) << 23); + InterCast o; + o.ivalue = (input & 0x7fff) << 13; // exponent/mantissa bits + o.fvalue *= magic.fvalue; // exponent adjust + if (o.fvalue >= was_infnan.fvalue) // make sure Inf/NaN survive + o.ivalue |= 255 << 23; + o.ivalue |= (input & 0x8000) << 16; // sign bit + return o.fvalue; + } + + class Random + { + private: + unsigned int seed; + public: + Random(int seed) + { + this->seed = seed; + } + int Next() // random between 0 and RandMax (currently 0x7fff) + { + return ((seed = ((seed << 12) + 150889L) % 714025) & 0x7fff); + } + int Next(int min, int max) // inclusive min, exclusive max + { + unsigned int a = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF); + unsigned int b = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF); + unsigned int r = (a << 16) + b; + return min + r % (max - min); + } + float NextFloat() + { + return ((Next() << 15) + Next()) / ((float)(1 << 30)); + } + float NextFloat(float valMin, float valMax) + { + return valMin + (valMax - valMin) * NextFloat(); + } + static int RandMax() + { + return 0x7fff; + } + }; + } +} + +#endif |
